@decodo/mcp-server 1.0.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 +169 -0
- package/build/clients/scraper-api-client.js +48 -0
- package/build/clients/scraper-api-client.js.map +1 -0
- package/build/clients/types.js +3 -0
- package/build/clients/types.js.map +1 -0
- package/build/constants.js +11 -0
- package/build/constants.js.map +1 -0
- package/build/index.js +37 -0
- package/build/index.js.map +1 -0
- package/build/sapi-mcp-server.js +40 -0
- package/build/sapi-mcp-server.js.map +1 -0
- package/build/tools/amazon-search-parsed-tool.js +46 -0
- package/build/tools/amazon-search-parsed-tool.js.map +1 -0
- package/build/tools/google-search-parsed-tool.js +54 -0
- package/build/tools/google-search-parsed-tool.js.map +1 -0
- package/build/tools/index.js +22 -0
- package/build/tools/index.js.map +1 -0
- package/build/tools/reddit-post-tool.js +34 -0
- package/build/tools/reddit-post-tool.js.map +1 -0
- package/build/tools/reddit-subreddit-tool.js +34 -0
- package/build/tools/reddit-subreddit-tool.js.map +1 -0
- package/build/tools/scrape-as-markdown-tool.js +70 -0
- package/build/tools/scrape-as-markdown-tool.js.map +1 -0
- package/build/tools/scrape-tool.js +70 -0
- package/build/tools/scrape-tool.js.map +1 -0
- package/build/types.js +3 -0
- package/build/types.js.map +1 -0
- package/build/utils.js +21 -0
- package/build/utils.js.map +1 -0
- package/build/zod/zod-types.js +25 -0
- package/build/zod/zod-types.js.map +1 -0
- package/package.json +36 -0
package/README.md
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Decodo MCP Server
|
|
2
|
+
|
|
3
|
+
[](https://smithery.ai/server/@Decodo/decodo-mcp-server)
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://dashboard.decodo.com/register?page=scrapers%2Fpricing&utm_source=github.com&utm_medium=social&utm_campaign=scraper_api_github"><img src="https://github.com/user-attachments/assets/13b08523-32b0-4c85-8e99-580d7c2a9055"></a>
|
|
7
|
+
|
|
8
|
+
[](https://discord.gg/Ja8dqKgvbZ)
|
|
9
|
+
|
|
10
|
+
This repository provides a Model Context Protocol (MCP) server that connects LLMs and applications
|
|
11
|
+
to Decodo's platform. The server facilitates integration between MCP-compatible clients and Decodo's
|
|
12
|
+
services, streamlining access to our tools and capabilities.
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- Easy web data access. Simplified retrieval of information from websites and online sources.
|
|
17
|
+
- Geographic flexibility. Access content regardless of regional restrictions.
|
|
18
|
+
- Enhanced privacy. Browse and collect data while maintaining anonymity.
|
|
19
|
+
- Reliable scraping. Advanced techniques to avoid detection and blocks.
|
|
20
|
+
- Simple integration. Seamless setup with popular MCP clients like Claude Desktop, Cursor, and
|
|
21
|
+
Windsurf.
|
|
22
|
+
|
|
23
|
+
## Quick start via Smithery (Recommended)
|
|
24
|
+
|
|
25
|
+
Visit the `decodo-mcp-server` page on
|
|
26
|
+
[Smithery](https://smithery.ai/server/@Decodo/decodo-mcp-server), select your preferred MCP client
|
|
27
|
+
and generate installation instructions.
|
|
28
|
+
|
|
29
|
+

|
|
30
|
+
|
|
31
|
+
## Obtain Web Scraping API credentials
|
|
32
|
+
|
|
33
|
+
You'll need the Decodo Advanced Web Scraping API credentials, which you can get by starting a free
|
|
34
|
+
trial on the [dashboard](https://dashboard.decodo.com/). Once you have a plan activated, take a note
|
|
35
|
+
of your generated username and password:
|
|
36
|
+
|
|
37
|
+

|
|
38
|
+
|
|
39
|
+
## Running the MCP server locally (manual)
|
|
40
|
+
|
|
41
|
+
### Prerequisites
|
|
42
|
+
|
|
43
|
+
- Node.js 18.0+
|
|
44
|
+
- An MCP client - popular choices are [Claude Desktop](https://claude.ai/download) and
|
|
45
|
+
[Cursor](https://www.cursor.com/)
|
|
46
|
+
|
|
47
|
+
### Step-by-step guide
|
|
48
|
+
|
|
49
|
+
1. Clone this repository:
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
git clone https://github.com/Decodo/decodo-mcp-server
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
2. Run the following commands in the terminal:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
cd decodo-mcp-server
|
|
59
|
+
npm install
|
|
60
|
+
npm run build
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
3. Take note of your build location:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
cd build/
|
|
67
|
+
pwd
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Adding `index.js` to the end of this directory, your build file location should look something like
|
|
71
|
+
this:
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
/Users/your.user/projects/decodo-mcp/build/index.js
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
4. Update your MCP client with the server information:
|
|
78
|
+
|
|
79
|
+
### Claude Desktop
|
|
80
|
+
|
|
81
|
+
[Follow the guide here](https://modelcontextprotocol.io/quickstart/user) to find the setup file,
|
|
82
|
+
then update `claude_desktop_config.json` to look like this:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
{
|
|
86
|
+
"mcpServers": {
|
|
87
|
+
"decodo-mcp": {
|
|
88
|
+
"command": "node",
|
|
89
|
+
"args": ["/Users/your.user/projects/decodo-mcp/build/index.js"],
|
|
90
|
+
"env": {
|
|
91
|
+
"SCRAPER_API_USERNAME": "your_username",
|
|
92
|
+
"SCRAPER_API_PASSWORD": "your_password"
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Cursor
|
|
101
|
+
|
|
102
|
+
For installation instructions, see the
|
|
103
|
+
[Cursor documentation](https://docs.cursor.com/context/model-context-protocol#installing-mcp-servers).
|
|
104
|
+
|
|
105
|
+
## Tools
|
|
106
|
+
|
|
107
|
+
The server exposes the following tools:
|
|
108
|
+
|
|
109
|
+
| Tool | Description | Example prompt |
|
|
110
|
+
| ---------------------- | ------------------------------------------------------------------------------------------ | ---------------------------------------------------------------- |
|
|
111
|
+
| `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. |
|
|
112
|
+
| `google_search_parsed` | Scrapes Google Search for a given query, and returns parsed results. | Scrape Google Search for shoes and tell me the top position. |
|
|
113
|
+
| `amazon_search_parsed` | Scrapes Amazon Search for a given query, and returns parsed results. | Scrape Amazon Search for toothbrushes |
|
|
114
|
+
|
|
115
|
+
## Parameters
|
|
116
|
+
|
|
117
|
+
The following parameters are inferred from user prompts:
|
|
118
|
+
|
|
119
|
+
| Parameter | Description |
|
|
120
|
+
| -------------- | ---------------------------------------------------------------------------------------------------- |
|
|
121
|
+
| `jsRender` | Renders target URL in a headless browser. |
|
|
122
|
+
| `geo` | Sets the country from which the request will originate. |
|
|
123
|
+
| `locale` | Sets the locale of the request. |
|
|
124
|
+
| `tokenLimit` | Truncates the response content up to this limit. Useful if the context window is small. |
|
|
125
|
+
| `fullResponse` | Skips automatic truncation and returns full content. If context window is small, may throw warnings. |
|
|
126
|
+
|
|
127
|
+
## Examples
|
|
128
|
+
|
|
129
|
+
### Scraping geo-restricted content
|
|
130
|
+
|
|
131
|
+
Query your AI agent with the following prompt:
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
Scrape peacock.com from a German IP address and tell me the pricing.
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
This prompt will say that peacock.com is geo-restricted. To bypass the geo-restriction:
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
Scrape peacock.com from a US IP address and tell me the pricing.
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Limiting number of response tokens
|
|
144
|
+
|
|
145
|
+
If your agent has a small context window, the content returned from scraping will be automatically
|
|
146
|
+
truncated, in order to avoid context-overflow. You can increase the number of tokens returned within
|
|
147
|
+
your prompt:
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
Scrape hacker news, return 50k tokens.
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
If your agent has a big context window, tell it to return `full content`:
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
Scrape hacker news, return full content.
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Related repositories
|
|
160
|
+
|
|
161
|
+
[Web Scraping API](https://github.com/Decodo/Web-Scraping-API)
|
|
162
|
+
|
|
163
|
+
[Google Maps scraper](https://github.com/Decodo/google-maps-scraper)
|
|
164
|
+
|
|
165
|
+
[Amazon scraper](https://github.com/Decodo/Amazon-scraper)
|
|
166
|
+
|
|
167
|
+
## License
|
|
168
|
+
|
|
169
|
+
All code is released under the [MIT License](https://github.com/Decodo/Decodo/blob/master/LICENSE).
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.ScraperApiClient = void 0;
|
|
18
|
+
const axios_1 = __importDefault(require("axios"));
|
|
19
|
+
class ScraperApiClient {
|
|
20
|
+
constructor({ auth }) {
|
|
21
|
+
this.transformScrapingParams = ({ scrapingParams, }) => {
|
|
22
|
+
const { jsRender } = scrapingParams, rest = __rest(scrapingParams, ["jsRender"]);
|
|
23
|
+
const transformed = Object.assign(Object.assign({}, (jsRender && { headless: 'html' })), rest);
|
|
24
|
+
return transformed;
|
|
25
|
+
};
|
|
26
|
+
this.transformResponse = ({ res }) => {
|
|
27
|
+
const content = res.data.results[0].content;
|
|
28
|
+
return Object.assign(Object.assign({}, res), { data: content });
|
|
29
|
+
};
|
|
30
|
+
this.scrape = async ({ scrapingParams }) => {
|
|
31
|
+
const transformedParams = this.transformScrapingParams({ scrapingParams });
|
|
32
|
+
const res = await axios_1.default.request({
|
|
33
|
+
url: 'https://scraper-api.decodo.com/v2/scrape',
|
|
34
|
+
method: 'POST',
|
|
35
|
+
headers: {
|
|
36
|
+
authorization: `Basic ${this.auth}`,
|
|
37
|
+
'x-integration': 'mcp',
|
|
38
|
+
},
|
|
39
|
+
data: Object.assign({}, transformedParams),
|
|
40
|
+
});
|
|
41
|
+
const response = this.transformResponse({ res });
|
|
42
|
+
return response;
|
|
43
|
+
};
|
|
44
|
+
this.auth = auth;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.ScraperApiClient = ScraperApiClient;
|
|
48
|
+
//# sourceMappingURL=scraper-api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scraper-api-client.js","sourceRoot":"","sources":["../../src/clients/scraper-api-client.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,kDAA6C;AAI7C,MAAa,gBAAgB;IAG3B,YAAY,EAAE,IAAI,EAAoB;QAItC,4BAAuB,GAAG,CAAC,EACzB,cAAc,GAGf,EAAoB,EAAE;YACrB,MAAM,EAAE,QAAQ,KAAc,cAAc,EAAvB,IAAI,UAAK,cAAc,EAAtC,YAAqB,CAAiB,CAAC;YAC7C,MAAM,WAAW,mCAAQ,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,GAAK,IAAI,CAAE,CAAC;YAEvE,OAAO,WAAW,CAAC;QACrB,CAAC,CAAC;QAEF,sBAAiB,GAAG,CAAI,EAAE,GAAG,EAAqD,EAAE,EAAE;YACpF,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAE5C,uCAAY,GAAG,KAAE,IAAI,EAAE,OAAO,IAAG;QACnC,CAAC,CAAC;QAEF,WAAM,GAAG,KAAK,EAAc,EAAE,cAAc,EAAyC,EAAE,EAAE;YACvF,MAAM,iBAAiB,GAAG,IAAI,CAAC,uBAAuB,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC;YAE3E,MAAM,GAAG,GAAG,MAAM,eAAK,CAAC,OAAO,CAA4B;gBACzD,GAAG,EAAE,0CAA0C;gBAC/C,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,aAAa,EAAE,SAAS,IAAI,CAAC,IAAI,EAAE;oBACnC,eAAe,EAAE,KAAK;iBACvB;gBACD,IAAI,oBACC,iBAAiB,CACrB;aACF,CAAC,CAAC;YAEH,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;YAEjD,OAAO,QAAQ,CAAC;QAClB,CAAC,CAAC;QAtCA,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CAsCF;AA3CD,4CA2CC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/clients/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SCRAPER_API_TARGETS = void 0;
|
|
4
|
+
var SCRAPER_API_TARGETS;
|
|
5
|
+
(function (SCRAPER_API_TARGETS) {
|
|
6
|
+
SCRAPER_API_TARGETS["GOOGLE_SEARCH"] = "google_search";
|
|
7
|
+
SCRAPER_API_TARGETS["AMAZON_SEARCH"] = "amazon_search";
|
|
8
|
+
SCRAPER_API_TARGETS["REDDIT_POST"] = "reddit_post";
|
|
9
|
+
SCRAPER_API_TARGETS["REDDIT_SUBREDDIT"] = "reddit_subreddit";
|
|
10
|
+
})(SCRAPER_API_TARGETS || (exports.SCRAPER_API_TARGETS = SCRAPER_API_TARGETS = {}));
|
|
11
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAA,IAAY,mBAMX;AAND,WAAY,mBAAmB;IAC7B,sDAA+B,CAAA;IAC/B,sDAA+B,CAAA;IAE/B,kDAA2B,CAAA;IAC3B,4DAAqC,CAAA;AACvC,CAAC,EANW,mBAAmB,mCAAnB,mBAAmB,QAM9B"}
|
package/build/index.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
require("dotenv/config");
|
|
4
|
+
const process_1 = require("process");
|
|
5
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
6
|
+
const sapi_mcp_server_1 = require("./sapi-mcp-server");
|
|
7
|
+
if (process.env.ENABLE_MCPS_LOGGER) {
|
|
8
|
+
import('mcps-logger/console');
|
|
9
|
+
}
|
|
10
|
+
const parseEnvsOrExit = () => {
|
|
11
|
+
const envs = ['SCRAPER_API_USERNAME', 'SCRAPER_API_PASSWORD'];
|
|
12
|
+
for (const envKey of envs) {
|
|
13
|
+
if (!process.env[envKey]) {
|
|
14
|
+
(0, process_1.exit)(`env ${envKey} missing`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
sapiUsername: process.env['SCRAPER_API_USERNAME'],
|
|
19
|
+
sapiPassword: process.env['SCRAPER_API_PASSWORD'],
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
async function main() {
|
|
23
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
24
|
+
// if there are no envs, some MCP clients will fail silently
|
|
25
|
+
const { sapiUsername, sapiPassword } = parseEnvsOrExit();
|
|
26
|
+
const sapiMcpServer = new sapi_mcp_server_1.ScraperAPIMCPServer({
|
|
27
|
+
sapiUsername,
|
|
28
|
+
sapiPassword,
|
|
29
|
+
});
|
|
30
|
+
await sapiMcpServer.connect(transport);
|
|
31
|
+
console.error('MCP Server running on stdio');
|
|
32
|
+
}
|
|
33
|
+
main().catch(error => {
|
|
34
|
+
console.error('Fatal error in main():', error);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
});
|
|
37
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,yBAAuB;AAEvB,qCAA+B;AAC/B,wEAAiF;AACjF,uDAAwD;AAExD,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC;IACnC,MAAM,CAAC,qBAAqB,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,eAAe,GAAG,GAA2B,EAAE;IACnD,MAAM,IAAI,GAAG,CAAC,sBAAsB,EAAE,sBAAsB,CAAC,CAAC;IAE9D,KAAK,MAAM,MAAM,IAAI,IAAI,EAAE,CAAC;QAC1B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACzB,IAAA,cAAI,EAAC,OAAO,MAAM,UAAU,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED,OAAO;QACL,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAW;QAC3D,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAW;KAC5D,CAAC;AACJ,CAAC,CAAC;AAEF,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,+BAAoB,EAAE,CAAC;IAE7C,4DAA4D;IAC5D,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,eAAe,EAAE,CAAC;IAEzD,MAAM,aAAa,GAAG,IAAI,qCAAmB,CAAC;QAC5C,YAAY;QACZ,YAAY;KACb,CAAC,CAAC;IACH,MAAM,aAAa,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEvC,OAAO,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;AAC/C,CAAC;AAED,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,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ScraperAPIMCPServer = void 0;
|
|
4
|
+
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
5
|
+
const scraper_api_client_1 = require("./clients/scraper-api-client");
|
|
6
|
+
const tools_1 = require("./tools");
|
|
7
|
+
class ScraperAPIMCPServer {
|
|
8
|
+
constructor({ sapiUsername, sapiPassword }) {
|
|
9
|
+
this.server = new mcp_js_1.McpServer({
|
|
10
|
+
name: 'decodo',
|
|
11
|
+
version: '0.1.0',
|
|
12
|
+
capabilities: {
|
|
13
|
+
logging: {},
|
|
14
|
+
resources: {},
|
|
15
|
+
tools: {},
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
const auth = Buffer.from(`${sapiUsername}:${sapiPassword}`).toString('base64');
|
|
19
|
+
this.sapiClient = new scraper_api_client_1.ScraperApiClient({ auth });
|
|
20
|
+
this.registerTools();
|
|
21
|
+
this.registerResources();
|
|
22
|
+
}
|
|
23
|
+
connect(transport) {
|
|
24
|
+
this.server.connect(transport);
|
|
25
|
+
}
|
|
26
|
+
registerTools() {
|
|
27
|
+
// scrape
|
|
28
|
+
tools_1.ScrapeAsMarkdownTool.register({ server: this.server, sapiClient: this.sapiClient });
|
|
29
|
+
// targets
|
|
30
|
+
tools_1.GoogleSearchParsedTool.register({ server: this.server, sapiClient: this.sapiClient });
|
|
31
|
+
tools_1.AmazonSearchParsedTool.register({ server: this.server, sapiClient: this.sapiClient });
|
|
32
|
+
tools_1.RedditPostTool.register({ server: this.server, sapiClient: this.sapiClient });
|
|
33
|
+
tools_1.RedditSubredditTool.register({ server: this.server, sapiClient: this.sapiClient });
|
|
34
|
+
}
|
|
35
|
+
registerResources() {
|
|
36
|
+
// todo: expose info about all targets available
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.ScraperAPIMCPServer = ScraperAPIMCPServer;
|
|
40
|
+
//# sourceMappingURL=sapi-mcp-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sapi-mcp-server.js","sourceRoot":"","sources":["../src/sapi-mcp-server.ts"],"names":[],"mappings":";;;AAAA,oEAAoE;AAEpE,qEAAgE;AAChE,mCAMiB;AAEjB,MAAa,mBAAmB;IAK9B,YAAY,EAAE,YAAY,EAAE,YAAY,EAAkD;QACxF,IAAI,CAAC,MAAM,GAAG,IAAI,kBAAS,CAAC;YAC1B,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,OAAO;YAChB,YAAY,EAAE;gBACZ,OAAO,EAAE,EAAE;gBACX,SAAS,EAAE,EAAE;gBACb,KAAK,EAAE,EAAE;aACV;SACF,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,YAAY,IAAI,YAAY,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAE/E,IAAI,CAAC,UAAU,GAAG,IAAI,qCAAgB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QAEjD,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAC3B,CAAC;IAED,OAAO,CAAC,SAA+B;QACrC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACjC,CAAC;IAED,aAAa;QACX,SAAS;QACT,4BAAoB,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QAEpF,UAAU;QACV,8BAAsB,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QACtF,8BAAsB,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QACtF,sBAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QAC9E,2BAAmB,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IACrF,CAAC;IAED,iBAAiB;QACf,gDAAgD;IAClD,CAAC;CACF;AA1CD,kDA0CC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
var _a;
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.AmazonSearchParsedTool = void 0;
|
|
8
|
+
const zod_1 = __importDefault(require("zod"));
|
|
9
|
+
const constants_1 = require("../constants");
|
|
10
|
+
const utils_1 = require("../utils");
|
|
11
|
+
const zod_types_1 = require("../zod/zod-types");
|
|
12
|
+
class AmazonSearchParsedTool {
|
|
13
|
+
}
|
|
14
|
+
exports.AmazonSearchParsedTool = AmazonSearchParsedTool;
|
|
15
|
+
_a = AmazonSearchParsedTool;
|
|
16
|
+
AmazonSearchParsedTool.FIELDS_WITH_HIGH_CHAR_COUNT = ['suggested', 'amazons_choices', 'refinements'];
|
|
17
|
+
AmazonSearchParsedTool.transformAutoParsedResponse = ({ obj }) => {
|
|
18
|
+
for (const fieldToRemove of _a.FIELDS_WITH_HIGH_CHAR_COUNT) {
|
|
19
|
+
obj = (0, utils_1.removeKeyFromNestedObject)({ obj, keyToRemove: fieldToRemove });
|
|
20
|
+
}
|
|
21
|
+
const text = JSON.stringify(obj);
|
|
22
|
+
return text;
|
|
23
|
+
};
|
|
24
|
+
AmazonSearchParsedTool.register = ({ server, sapiClient, }) => {
|
|
25
|
+
server.registerTool('amazon_search_parsed', {
|
|
26
|
+
description: 'Scrape Amazon Search results with automatic parsing',
|
|
27
|
+
inputSchema: {
|
|
28
|
+
query: zod_1.default.string().describe('Search query'),
|
|
29
|
+
geo: zod_types_1.zodGeo,
|
|
30
|
+
jsRender: zod_types_1.zodJsRender,
|
|
31
|
+
},
|
|
32
|
+
}, async (scrapingParams) => {
|
|
33
|
+
const params = Object.assign(Object.assign({}, scrapingParams), { target: constants_1.SCRAPER_API_TARGETS.AMAZON_SEARCH, parse: true });
|
|
34
|
+
const { data } = await sapiClient.scrape({ scrapingParams: params });
|
|
35
|
+
const text = _a.transformAutoParsedResponse({ obj: data });
|
|
36
|
+
return {
|
|
37
|
+
content: [
|
|
38
|
+
{
|
|
39
|
+
type: 'text',
|
|
40
|
+
text,
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=amazon-search-parsed-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"amazon-search-parsed-tool.js","sourceRoot":"","sources":["../../src/tools/amazon-search-parsed-tool.ts"],"names":[],"mappings":";;;;;;;AAAA,8CAAoB;AAIpB,4CAAmD;AACnD,oCAAqD;AACrD,gDAAkE;AAElE,MAAa,sBAAsB;;AAAnC,wDAoDC;;AAnDQ,kDAA2B,GAAG,CAAC,WAAW,EAAE,iBAAiB,EAAE,aAAa,CAAC,AAAlD,CAAmD;AAE9E,kDAA2B,GAAG,CAAC,EAAE,GAAG,EAAmB,EAAU,EAAE;IACxE,KAAK,MAAM,aAAa,IAAI,EAAsB,CAAC,2BAA2B,EAAE,CAAC;QAC/E,GAAG,GAAG,IAAA,iCAAyB,EAAC,EAAE,GAAG,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAEjC,OAAO,IAAI,CAAC;AACd,CAAC,AARiC,CAQhC;AAEK,+BAAQ,GAAG,CAAC,EACjB,MAAM,EACN,UAAU,GAIX,EAAE,EAAE;IACH,MAAM,CAAC,YAAY,CACjB,sBAAsB,EACtB;QACE,WAAW,EAAE,qDAAqD;QAClE,WAAW,EAAE;YACX,KAAK,EAAE,aAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;YAC1C,GAAG,EAAE,kBAAM;YACX,QAAQ,EAAE,uBAAW;SACtB;KACF,EACD,KAAK,EAAE,cAAiC,EAAE,EAAE;QAC1C,MAAM,MAAM,GAAG,gCACV,cAAc,KACjB,MAAM,EAAE,+BAAmB,CAAC,aAAa,EACzC,KAAK,EAAE,IAAI,GACe,CAAC;QAE7B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,UAAU,CAAC,MAAM,CAAS,EAAE,cAAc,EAAE,MAAM,EAAE,CAAC,CAAC;QAE7E,MAAM,IAAI,GAAG,EAAI,CAAC,2BAA2B,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;QAE7D,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI;iBACL;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC,AAtCc,CAsCb"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
var _a;
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.GoogleSearchParsedTool = void 0;
|
|
8
|
+
const zod_1 = __importDefault(require("zod"));
|
|
9
|
+
const constants_1 = require("../constants");
|
|
10
|
+
const utils_1 = require("../utils");
|
|
11
|
+
const zod_types_1 = require("../zod/zod-types");
|
|
12
|
+
class GoogleSearchParsedTool {
|
|
13
|
+
}
|
|
14
|
+
exports.GoogleSearchParsedTool = GoogleSearchParsedTool;
|
|
15
|
+
_a = GoogleSearchParsedTool;
|
|
16
|
+
GoogleSearchParsedTool.FIELDS_WITH_HIGH_CHAR_COUNT = [
|
|
17
|
+
'images',
|
|
18
|
+
'image_data',
|
|
19
|
+
'related_searches_urls',
|
|
20
|
+
'factoids',
|
|
21
|
+
'people_also_buy_from',
|
|
22
|
+
'what_people_are_saying',
|
|
23
|
+
];
|
|
24
|
+
GoogleSearchParsedTool.transformAutoParsedResponse = ({ obj }) => {
|
|
25
|
+
for (const fieldToRemove of _a.FIELDS_WITH_HIGH_CHAR_COUNT) {
|
|
26
|
+
obj = (0, utils_1.removeKeyFromNestedObject)({ obj, keyToRemove: fieldToRemove });
|
|
27
|
+
}
|
|
28
|
+
const text = JSON.stringify(obj);
|
|
29
|
+
return text;
|
|
30
|
+
};
|
|
31
|
+
GoogleSearchParsedTool.register = ({ server, sapiClient, }) => {
|
|
32
|
+
server.registerTool('google_search_parsed', {
|
|
33
|
+
description: 'Scrape Google Search results with automatic parsing',
|
|
34
|
+
inputSchema: {
|
|
35
|
+
query: zod_1.default.string().describe('Search query'),
|
|
36
|
+
geo: zod_types_1.zodGeo,
|
|
37
|
+
locale: zod_types_1.zodLocale,
|
|
38
|
+
jsRender: zod_types_1.zodJsRender,
|
|
39
|
+
},
|
|
40
|
+
}, async (scrapingParams) => {
|
|
41
|
+
const params = Object.assign(Object.assign({}, scrapingParams), { target: constants_1.SCRAPER_API_TARGETS.GOOGLE_SEARCH, parse: true });
|
|
42
|
+
const { data } = await sapiClient.scrape({ scrapingParams: params });
|
|
43
|
+
const text = _a.transformAutoParsedResponse({ obj: data });
|
|
44
|
+
return {
|
|
45
|
+
content: [
|
|
46
|
+
{
|
|
47
|
+
type: 'text',
|
|
48
|
+
text,
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
};
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=google-search-parsed-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google-search-parsed-tool.js","sourceRoot":"","sources":["../../src/tools/google-search-parsed-tool.ts"],"names":[],"mappings":";;;;;;;AAAA,8CAAoB;AAIpB,4CAAmD;AACnD,oCAAqD;AACrD,gDAAkE;AAElE,MAAa,sBAAsB;;AAAnC,wDA4DC;;AA3DQ,kDAA2B,GAAG;IACnC,QAAQ;IACR,YAAY;IACZ,uBAAuB;IACvB,UAAU;IACV,sBAAsB;IACtB,wBAAwB;CACzB,AAPiC,CAOhC;AAEK,kDAA2B,GAAG,CAAC,EAAE,GAAG,EAAmB,EAAU,EAAE;IACxE,KAAK,MAAM,aAAa,IAAI,EAAsB,CAAC,2BAA2B,EAAE,CAAC;QAC/E,GAAG,GAAG,IAAA,iCAAyB,EAAC,EAAE,GAAG,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAEjC,OAAO,IAAI,CAAC;AACd,CAAC,AARiC,CAQhC;AAEK,+BAAQ,GAAG,CAAC,EACjB,MAAM,EACN,UAAU,GAIX,EAAE,EAAE;IACH,MAAM,CAAC,YAAY,CACjB,sBAAsB,EACtB;QACE,WAAW,EAAE,qDAAqD;QAClE,WAAW,EAAE;YACX,KAAK,EAAE,aAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;YAC1C,GAAG,EAAE,kBAAM;YACX,MAAM,EAAE,qBAAS;YACjB,QAAQ,EAAE,uBAAW;SACtB;KACF,EACD,KAAK,EAAE,cAAiC,EAAE,EAAE;QAC1C,MAAM,MAAM,GAAG,gCACV,cAAc,KACjB,MAAM,EAAE,+BAAmB,CAAC,aAAa,EACzC,KAAK,EAAE,IAAI,GACe,CAAC;QAE7B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,UAAU,CAAC,MAAM,CAAS,EAAE,cAAc,EAAE,MAAM,EAAE,CAAC,CAAC;QAE7E,MAAM,IAAI,GAAG,EAAI,CAAC,2BAA2B,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;QAE7D,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI;iBACL;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC,AAvCc,CAuCb"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./amazon-search-parsed-tool"), exports);
|
|
18
|
+
__exportStar(require("./google-search-parsed-tool"), exports);
|
|
19
|
+
__exportStar(require("./reddit-subreddit-tool"), exports);
|
|
20
|
+
__exportStar(require("./reddit-post-tool"), exports);
|
|
21
|
+
__exportStar(require("./scrape-as-markdown-tool"), exports);
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8DAA4C;AAC5C,8DAA4C;AAC5C,0DAAwC;AACxC,qDAAmC;AACnC,4DAA0C"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
var _a;
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.RedditPostTool = void 0;
|
|
8
|
+
const zod_1 = __importDefault(require("zod"));
|
|
9
|
+
const constants_1 = require("../constants");
|
|
10
|
+
class RedditPostTool {
|
|
11
|
+
}
|
|
12
|
+
exports.RedditPostTool = RedditPostTool;
|
|
13
|
+
_a = RedditPostTool;
|
|
14
|
+
RedditPostTool.register = ({ server, sapiClient, }) => {
|
|
15
|
+
server.registerTool('reddit_post', {
|
|
16
|
+
description: 'Scrape a specific Reddit post',
|
|
17
|
+
inputSchema: {
|
|
18
|
+
url: zod_1.default.string().describe('reddit post URL'),
|
|
19
|
+
},
|
|
20
|
+
}, async (scrapingParams) => {
|
|
21
|
+
const params = Object.assign(Object.assign({}, scrapingParams), { target: constants_1.SCRAPER_API_TARGETS.REDDIT_POST });
|
|
22
|
+
const { data } = await sapiClient.scrape({ scrapingParams: params });
|
|
23
|
+
const text = JSON.stringify(data, null, 2);
|
|
24
|
+
return {
|
|
25
|
+
content: [
|
|
26
|
+
{
|
|
27
|
+
type: 'text',
|
|
28
|
+
text,
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=reddit-post-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reddit-post-tool.js","sourceRoot":"","sources":["../../src/tools/reddit-post-tool.ts"],"names":[],"mappings":";;;;;;;AAAA,8CAAoB;AAIpB,4CAAmD;AAEnD,MAAa,cAAc;;AAA3B,wCAqCC;;AApCQ,uBAAQ,GAAG,CAAC,EACjB,MAAM,EACN,UAAU,GAIX,EAAE,EAAE;IACH,MAAM,CAAC,YAAY,CACjB,aAAa,EACb;QACE,WAAW,EAAE,+BAA+B;QAC5C,WAAW,EAAE;YACX,GAAG,EAAE,aAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC;SAC5C;KACF,EACD,KAAK,EAAE,cAAiC,EAAE,EAAE;QAC1C,MAAM,MAAM,GAAG,gCACV,cAAc,KACjB,MAAM,EAAE,+BAAmB,CAAC,WAAW,GACb,CAAC;QAE7B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,UAAU,CAAC,MAAM,CAAS,EAAE,cAAc,EAAE,MAAM,EAAE,CAAC,CAAC;QAE7E,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAE3C,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI;iBACL;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC,AAnCc,CAmCb"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
var _a;
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.RedditSubredditTool = void 0;
|
|
8
|
+
const zod_1 = __importDefault(require("zod"));
|
|
9
|
+
const constants_1 = require("../constants");
|
|
10
|
+
class RedditSubredditTool {
|
|
11
|
+
}
|
|
12
|
+
exports.RedditSubredditTool = RedditSubredditTool;
|
|
13
|
+
_a = RedditSubredditTool;
|
|
14
|
+
RedditSubredditTool.register = ({ server, sapiClient, }) => {
|
|
15
|
+
server.registerTool('reddit_subreddit', {
|
|
16
|
+
description: 'Scrape Reddit subreddit results with automatic parsing',
|
|
17
|
+
inputSchema: {
|
|
18
|
+
url: zod_1.default.string().describe('URL to subreddit'),
|
|
19
|
+
},
|
|
20
|
+
}, async (scrapingParams) => {
|
|
21
|
+
const params = Object.assign(Object.assign({}, scrapingParams), { target: constants_1.SCRAPER_API_TARGETS.REDDIT_SUBREDDIT });
|
|
22
|
+
const { data } = await sapiClient.scrape({ scrapingParams: params });
|
|
23
|
+
const text = JSON.stringify(data, null, 2);
|
|
24
|
+
return {
|
|
25
|
+
content: [
|
|
26
|
+
{
|
|
27
|
+
type: 'text',
|
|
28
|
+
text,
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=reddit-subreddit-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reddit-subreddit-tool.js","sourceRoot":"","sources":["../../src/tools/reddit-subreddit-tool.ts"],"names":[],"mappings":";;;;;;;AAAA,8CAAoB;AAIpB,4CAAmD;AAEnD,MAAa,mBAAmB;;AAAhC,kDAqCC;;AApCQ,4BAAQ,GAAG,CAAC,EACjB,MAAM,EACN,UAAU,GAIX,EAAE,EAAE;IACH,MAAM,CAAC,YAAY,CACjB,kBAAkB,EAClB;QACE,WAAW,EAAE,wDAAwD;QACrE,WAAW,EAAE;YACX,GAAG,EAAE,aAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;SAC7C;KACF,EACD,KAAK,EAAE,cAAiC,EAAE,EAAE;QAC1C,MAAM,MAAM,GAAG,gCACV,cAAc,KACjB,MAAM,EAAE,+BAAmB,CAAC,gBAAgB,GAClB,CAAC;QAE7B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,UAAU,CAAC,MAAM,CAAS,EAAE,cAAc,EAAE,MAAM,EAAE,CAAC,CAAC;QAE7E,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAE3C,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI;iBACL;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC,AAnCc,CAmCb"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
var _a;
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.ScrapeAsMarkdownTool = void 0;
|
|
8
|
+
const zod_1 = __importDefault(require("zod"));
|
|
9
|
+
const node_html_markdown_1 = require("node-html-markdown");
|
|
10
|
+
const zod_types_1 = require("../zod/zod-types");
|
|
11
|
+
class ScrapeAsMarkdownTool {
|
|
12
|
+
}
|
|
13
|
+
exports.ScrapeAsMarkdownTool = ScrapeAsMarkdownTool;
|
|
14
|
+
_a = ScrapeAsMarkdownTool;
|
|
15
|
+
ScrapeAsMarkdownTool.LARGE_CONTENT_SYMBOL_COUNT = 10000;
|
|
16
|
+
ScrapeAsMarkdownTool.isResponseOverLimit = (content) => {
|
|
17
|
+
return content.length > _a.LARGE_CONTENT_SYMBOL_COUNT;
|
|
18
|
+
};
|
|
19
|
+
ScrapeAsMarkdownTool.shouldTruncateResponse = ({ content, shouldShowFullResponse, }) => {
|
|
20
|
+
if (shouldShowFullResponse) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
return _a.isResponseOverLimit(content);
|
|
24
|
+
};
|
|
25
|
+
ScrapeAsMarkdownTool.truncateResponse = ({ content, limit }) => {
|
|
26
|
+
return content.substring(0, limit);
|
|
27
|
+
};
|
|
28
|
+
ScrapeAsMarkdownTool.transformResponse = ({ html, tokenLimit, shouldShowFullResponse, }) => {
|
|
29
|
+
const markdown = node_html_markdown_1.NodeHtmlMarkdown.translate(html, {});
|
|
30
|
+
if (_a.shouldTruncateResponse({ content: markdown, shouldShowFullResponse })) {
|
|
31
|
+
const truncated = _a.truncateResponse({
|
|
32
|
+
content: markdown,
|
|
33
|
+
limit: tokenLimit || _a.LARGE_CONTENT_SYMBOL_COUNT,
|
|
34
|
+
});
|
|
35
|
+
return { markdown: truncated, isTruncated: true };
|
|
36
|
+
}
|
|
37
|
+
return { markdown, isTruncated: false };
|
|
38
|
+
};
|
|
39
|
+
ScrapeAsMarkdownTool.register = ({ server, sapiClient, }) => {
|
|
40
|
+
server.tool('scrape_as_markdown', 'Scrape the contents of a website and return Markdown-formatted results', {
|
|
41
|
+
url: zod_1.default.string().describe('URL to scrape'),
|
|
42
|
+
geo: zod_types_1.zodGeo,
|
|
43
|
+
locale: zod_types_1.zodLocale,
|
|
44
|
+
jsRender: zod_types_1.zodJsRender,
|
|
45
|
+
tokenLimit: zod_types_1.zodTokenLimit,
|
|
46
|
+
fullResponse: zod_types_1.zodFullResponse,
|
|
47
|
+
}, async (scrapingParams) => {
|
|
48
|
+
const { data } = await sapiClient.scrape({ scrapingParams });
|
|
49
|
+
const { markdown, isTruncated } = _a.transformResponse({
|
|
50
|
+
html: data,
|
|
51
|
+
tokenLimit: scrapingParams.tokenLimit,
|
|
52
|
+
shouldShowFullResponse: scrapingParams.fullResponse,
|
|
53
|
+
});
|
|
54
|
+
return {
|
|
55
|
+
content: [
|
|
56
|
+
{
|
|
57
|
+
type: 'text',
|
|
58
|
+
text: isTruncated
|
|
59
|
+
? `The website content is over ${_a.LARGE_CONTENT_SYMBOL_COUNT} symbols, therefore, the content has been truncated. If you wish to obtain the full response, just say "full response". Alternatively, you say a specific token limit in the prompt.`
|
|
60
|
+
: 'Full website content retrieved.',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
type: 'text',
|
|
64
|
+
text: markdown,
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
};
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=scrape-as-markdown-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scrape-as-markdown-tool.js","sourceRoot":"","sources":["../../src/tools/scrape-as-markdown-tool.ts"],"names":[],"mappings":";;;;;;;AAAA,8CAAoB;AAIpB,2DAAsD;AACtD,gDAAkG;AAElG,MAAa,oBAAoB;;AAAjC,oDA4FC;;AA3FQ,+CAA0B,GAAG,KAAM,AAAT,CAAU;AAEpC,wCAAmB,GAAG,CAAC,OAAe,EAAE,EAAE;IAC/C,OAAO,OAAO,CAAC,MAAM,GAAG,EAAI,CAAC,0BAA0B,CAAC;AAC1D,CAAC,AAFyB,CAExB;AAEK,2CAAsB,GAAG,CAAC,EAC/B,OAAO,EACP,sBAAsB,GAIvB,EAAE,EAAE;IACH,IAAI,sBAAsB,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,EAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC3C,CAAC,AAZ4B,CAY3B;AAEK,qCAAgB,GAAG,CAAC,EAAE,OAAO,EAAE,KAAK,EAAsC,EAAE,EAAE;IACnF,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AACrC,CAAC,AAFsB,CAErB;AAEK,sCAAiB,GAAG,CAAC,EAC1B,IAAI,EACJ,UAAU,EACV,sBAAsB,GAKvB,EAAE,EAAE;IACH,MAAM,QAAQ,GAAG,qCAAgB,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAEtD,IAAI,EAAI,CAAC,sBAAsB,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,sBAAsB,EAAE,CAAC,EAAE,CAAC;QAC/E,MAAM,SAAS,GAAG,EAAI,CAAC,gBAAgB,CAAC;YACtC,OAAO,EAAE,QAAQ;YACjB,KAAK,EAAE,UAAU,IAAI,EAAI,CAAC,0BAA0B;SACrD,CAAC,CAAC;QAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IACpD,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;AAC1C,CAAC,AArBuB,CAqBtB;AAEK,6BAAQ,GAAG,CAAC,EACjB,MAAM,EACN,UAAU,GAIX,EAAE,EAAE;IACH,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB,wEAAwE,EACxE;QACE,GAAG,EAAE,aAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;QACzC,GAAG,EAAE,kBAAM;QACX,MAAM,EAAE,qBAAS;QACjB,QAAQ,EAAE,uBAAW;QACrB,UAAU,EAAE,yBAAa;QACzB,YAAY,EAAE,2BAAe;KAC9B,EACD,KAAK,EAAE,cAAiC,EAAE,EAAE;QAC1C,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC;QAE7D,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,EAAI,CAAC,iBAAiB,CAAC;YACvD,IAAI,EAAE,IAAI;YACV,UAAU,EAAE,cAAc,CAAC,UAAU;YACrC,sBAAsB,EAAE,cAAc,CAAC,YAAY;SACpD,CAAC,CAAC;QAEH,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,WAAW;wBACf,CAAC,CAAC,+BAA+B,EAAI,CAAC,0BAA0B,sLAAsL;wBACtP,CAAC,CAAC,iCAAiC;iBACtC;gBACD;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,QAAQ;iBACf;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC,AA3Cc,CA2Cb"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
var _a;
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.ScrapeTool = void 0;
|
|
8
|
+
const zod_1 = __importDefault(require("zod"));
|
|
9
|
+
const node_html_markdown_1 = require("node-html-markdown");
|
|
10
|
+
const zod_types_1 = require("../zod/zod-types");
|
|
11
|
+
class ScrapeTool {
|
|
12
|
+
}
|
|
13
|
+
exports.ScrapeTool = ScrapeTool;
|
|
14
|
+
_a = ScrapeTool;
|
|
15
|
+
ScrapeTool.LARGE_CONTENT_SYMBOL_COUNT = 10000;
|
|
16
|
+
ScrapeTool.isResponseOverLimit = (content) => {
|
|
17
|
+
return content.length > _a.LARGE_CONTENT_SYMBOL_COUNT;
|
|
18
|
+
};
|
|
19
|
+
ScrapeTool.shouldTruncateResponse = ({ content, shouldShowFullResponse, }) => {
|
|
20
|
+
if (shouldShowFullResponse) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
return _a.isResponseOverLimit(content);
|
|
24
|
+
};
|
|
25
|
+
ScrapeTool.truncateResponse = ({ content, limit }) => {
|
|
26
|
+
return content.substring(0, limit);
|
|
27
|
+
};
|
|
28
|
+
ScrapeTool.transformResponse = ({ html, tokenLimit, shouldShowFullResponse, }) => {
|
|
29
|
+
const markdown = node_html_markdown_1.NodeHtmlMarkdown.translate(html, {});
|
|
30
|
+
if (_a.shouldTruncateResponse({ content: markdown, shouldShowFullResponse })) {
|
|
31
|
+
const truncated = _a.truncateResponse({
|
|
32
|
+
content: markdown,
|
|
33
|
+
limit: tokenLimit || _a.LARGE_CONTENT_SYMBOL_COUNT,
|
|
34
|
+
});
|
|
35
|
+
return { markdown: truncated, isTruncated: true };
|
|
36
|
+
}
|
|
37
|
+
return { markdown, isTruncated: false };
|
|
38
|
+
};
|
|
39
|
+
ScrapeTool.register = ({ server, sapiClient, }) => {
|
|
40
|
+
server.tool('scrape', 'Scrape the contents of a website', {
|
|
41
|
+
url: zod_1.default.string().describe('URL to scrape'),
|
|
42
|
+
geo: zod_types_1.zodGeo,
|
|
43
|
+
locale: zod_types_1.zodLocale,
|
|
44
|
+
jsRender: zod_types_1.zodJsRender,
|
|
45
|
+
tokenLimit: zod_types_1.zodTokenLimit,
|
|
46
|
+
fullResponse: zod_types_1.zodFullResponse,
|
|
47
|
+
}, async (scrapingParams) => {
|
|
48
|
+
const { data } = await sapiClient.scrape({ scrapingParams });
|
|
49
|
+
const { markdown, isTruncated } = _a.transformResponse({
|
|
50
|
+
html: data,
|
|
51
|
+
tokenLimit: scrapingParams.tokenLimit,
|
|
52
|
+
shouldShowFullResponse: scrapingParams.fullResponse,
|
|
53
|
+
});
|
|
54
|
+
return {
|
|
55
|
+
content: [
|
|
56
|
+
{
|
|
57
|
+
type: 'text',
|
|
58
|
+
text: isTruncated
|
|
59
|
+
? `The website content is over ${_a.LARGE_CONTENT_SYMBOL_COUNT} symbols, therefore, I have truncated the content. If you wish to obtain the full response, just say "full response". Alternatively, you can tell me a specific token limit.`
|
|
60
|
+
: 'Full website content retrieved.',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
type: 'text',
|
|
64
|
+
text: markdown,
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
};
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=scrape-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scrape-tool.js","sourceRoot":"","sources":["../../src/tools/scrape-tool.ts"],"names":[],"mappings":";;;;;;;AAAA,8CAAoB;AAIpB,2DAAsD;AACtD,gDAAkG;AAElG,MAAa,UAAU;;AAAvB,gCA4FC;;AA3FQ,qCAA0B,GAAG,KAAM,AAAT,CAAU;AAEpC,8BAAmB,GAAG,CAAC,OAAe,EAAE,EAAE;IAC/C,OAAO,OAAO,CAAC,MAAM,GAAG,EAAI,CAAC,0BAA0B,CAAC;AAC1D,CAAC,AAFyB,CAExB;AAEK,iCAAsB,GAAG,CAAC,EAC/B,OAAO,EACP,sBAAsB,GAIvB,EAAE,EAAE;IACH,IAAI,sBAAsB,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,EAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC3C,CAAC,AAZ4B,CAY3B;AAEK,2BAAgB,GAAG,CAAC,EAAE,OAAO,EAAE,KAAK,EAAsC,EAAE,EAAE;IACnF,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AACrC,CAAC,AAFsB,CAErB;AAEK,4BAAiB,GAAG,CAAC,EAC1B,IAAI,EACJ,UAAU,EACV,sBAAsB,GAKvB,EAAE,EAAE;IACH,MAAM,QAAQ,GAAG,qCAAgB,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAEtD,IAAI,EAAI,CAAC,sBAAsB,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,sBAAsB,EAAE,CAAC,EAAE,CAAC;QAC/E,MAAM,SAAS,GAAG,EAAI,CAAC,gBAAgB,CAAC;YACtC,OAAO,EAAE,QAAQ;YACjB,KAAK,EAAE,UAAU,IAAI,EAAI,CAAC,0BAA0B;SACrD,CAAC,CAAC;QAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IACpD,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;AAC1C,CAAC,AArBuB,CAqBtB;AAEK,mBAAQ,GAAG,CAAC,EACjB,MAAM,EACN,UAAU,GAIX,EAAE,EAAE;IACH,MAAM,CAAC,IAAI,CACT,QAAQ,EACR,kCAAkC,EAClC;QACE,GAAG,EAAE,aAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;QACzC,GAAG,EAAE,kBAAM;QACX,MAAM,EAAE,qBAAS;QACjB,QAAQ,EAAE,uBAAW;QACrB,UAAU,EAAE,yBAAa;QACzB,YAAY,EAAE,2BAAe;KAC9B,EACD,KAAK,EAAE,cAAiC,EAAE,EAAE;QAC1C,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC;QAE7D,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,EAAI,CAAC,iBAAiB,CAAC;YACvD,IAAI,EAAE,IAAI;YACV,UAAU,EAAE,cAAc,CAAC,UAAU;YACrC,sBAAsB,EAAE,cAAc,CAAC,YAAY;SACpD,CAAC,CAAC;QAEH,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,WAAW;wBACf,CAAC,CAAC,+BAA+B,EAAI,CAAC,0BAA0B,8KAA8K;wBAC9O,CAAC,CAAC,iCAAiC;iBACtC;gBACD;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,QAAQ;iBACf;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC,AA3Cc,CA2Cb"}
|
package/build/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/build/utils.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.removeKeyFromNestedObject = void 0;
|
|
4
|
+
const removeKeyFromNestedObject = ({ obj, keyToRemove, }) => {
|
|
5
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
6
|
+
return obj;
|
|
7
|
+
}
|
|
8
|
+
if (Array.isArray(obj)) {
|
|
9
|
+
return obj.map(item => (0, exports.removeKeyFromNestedObject)({ obj: item, keyToRemove }));
|
|
10
|
+
}
|
|
11
|
+
const newObj = {};
|
|
12
|
+
for (const key in obj) {
|
|
13
|
+
if (key === keyToRemove) {
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
newObj[key] = (0, exports.removeKeyFromNestedObject)({ obj: obj[key], keyToRemove });
|
|
17
|
+
}
|
|
18
|
+
return newObj;
|
|
19
|
+
};
|
|
20
|
+
exports.removeKeyFromNestedObject = removeKeyFromNestedObject;
|
|
21
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;AAAO,MAAM,yBAAyB,GAAG,CAAC,EACxC,GAAG,EACH,WAAW,GAIZ,EAAU,EAAE;IACX,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QAC5C,OAAO,GAAG,CAAC;IACb,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAA,iCAAyB,EAAC,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;IAChF,CAAC;IAED,MAAM,MAAM,GAAG,EAAE,CAAC;IAElB,KAAK,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;QACtB,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;YACxB,SAAS;QACX,CAAC;QAED,MAAM,CAAC,GAAG,CAAC,GAAG,IAAA,iCAAyB,EAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AA1BW,QAAA,yBAAyB,6BA0BpC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.zodFullResponse = exports.zodTokenLimit = exports.zodJsRender = exports.zodLocale = exports.zodGeo = void 0;
|
|
7
|
+
const zod_1 = __importDefault(require("zod"));
|
|
8
|
+
exports.zodGeo = zod_1.default
|
|
9
|
+
.string()
|
|
10
|
+
.describe('Geolocation of the desired request, expressed as a country name')
|
|
11
|
+
.optional();
|
|
12
|
+
exports.zodLocale = zod_1.default.string().describe('Locale of the desired request').optional();
|
|
13
|
+
exports.zodJsRender = zod_1.default
|
|
14
|
+
.boolean()
|
|
15
|
+
.describe('Should the request be opened in a headless browser, false by default')
|
|
16
|
+
.optional();
|
|
17
|
+
exports.zodTokenLimit = zod_1.default
|
|
18
|
+
.number()
|
|
19
|
+
.describe(`The number of tokens to return in the response - anything above this limit will be truncated`)
|
|
20
|
+
.optional();
|
|
21
|
+
exports.zodFullResponse = zod_1.default
|
|
22
|
+
.boolean()
|
|
23
|
+
.describe(`If true, content will not be truncated`)
|
|
24
|
+
.optional();
|
|
25
|
+
//# sourceMappingURL=zod-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zod-types.js","sourceRoot":"","sources":["../../src/zod/zod-types.ts"],"names":[],"mappings":";;;;;;AAAA,8CAAoB;AAEP,QAAA,MAAM,GAAG,aAAC;KACpB,MAAM,EAAE;KACR,QAAQ,CAAC,iEAAiE,CAAC;KAC3E,QAAQ,EAAE,CAAC;AAED,QAAA,SAAS,GAAG,aAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC,CAAC,QAAQ,EAAE,CAAC;AAE5E,QAAA,WAAW,GAAG,aAAC;KACzB,OAAO,EAAE;KACT,QAAQ,CAAC,sEAAsE,CAAC;KAChF,QAAQ,EAAE,CAAC;AAED,QAAA,aAAa,GAAG,aAAC;KAC3B,MAAM,EAAE;KACR,QAAQ,CACP,8FAA8F,CAC/F;KACA,QAAQ,EAAE,CAAC;AAED,QAAA,eAAe,GAAG,aAAC;KAC7B,OAAO,EAAE;KACT,QAAQ,CAAC,wCAAwC,CAAC;KAClD,QAAQ,EAAE,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@decodo/mcp-server",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"bin": {
|
|
6
|
+
"decodo-mcp": "./build/index.js"
|
|
7
|
+
},
|
|
8
|
+
"main": "index.js",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc && chmod 755 build/index.js",
|
|
11
|
+
"dev": "pnpm run build && mcp-inspector",
|
|
12
|
+
"test": "jest"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [],
|
|
15
|
+
"author": "",
|
|
16
|
+
"license": "ISC",
|
|
17
|
+
"files": [
|
|
18
|
+
"build"
|
|
19
|
+
],
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@modelcontextprotocol/inspector": "^0.14.0",
|
|
22
|
+
"@types/jest": "^30.0.0",
|
|
23
|
+
"@types/node": "^24.0.0",
|
|
24
|
+
"jest": "^30.0.0",
|
|
25
|
+
"mcps-logger": "^1.0.0",
|
|
26
|
+
"ts-jest": "^29.4.0",
|
|
27
|
+
"typescript": "^5.8.3",
|
|
28
|
+
"zod": "^3.25.57"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@modelcontextprotocol/sdk": "^1.12.3",
|
|
32
|
+
"axios": "^1.9.0",
|
|
33
|
+
"dotenv": "^16.5.0",
|
|
34
|
+
"node-html-markdown": "^1.3.0"
|
|
35
|
+
}
|
|
36
|
+
}
|