Skip to content

Commit f551500

Browse files
Merge pull request #77 from brightdata/feat/tool-groups
feat: configurable tool group selection
2 parents b361cda + 5c188ca commit f551500

File tree

5 files changed

+315
-6
lines changed

5 files changed

+315
-6
lines changed

README.md

Lines changed: 97 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ https://mcp.brightdata.com/mcp?token=YOUR_API_TOKEN_HERE
114114
<tr>
115115
<th width="33%">⚡ Rapid Mode (Free tier)</th>
116116
<th width="33%">💎 Pro Mode</th>
117+
<th width="34%">🔧 Custom Mode</th>
117118
</tr>
118119
<tr>
119120
<td align="center">
@@ -129,7 +130,7 @@ https://mcp.brightdata.com/mcp?token=YOUR_API_TOKEN_HERE
129130
</td>
130131
<td align="center">
131132
<h3>Pay-as-you-go</h3>
132-
<p><strong>Every thing in rapid and 60+ Advanced Tools</strong></p>
133+
<p><strong>Everything in rapid plus 60+ tools</strong></p>
133134
<hr/>
134135
<p>✅ Browser Control<br/>
135136
✅ Web Data APIs<br/>
@@ -138,11 +139,105 @@ https://mcp.brightdata.com/mcp?token=YOUR_API_TOKEN_HERE
138139
<br/>
139140
<code>PRO_MODE=true</code>
140141
</td>
142+
<td align="center">
143+
<h3>Usage-based</h3>
144+
<p><strong>Pick the tools you need</strong></p>
145+
<hr/>
146+
<p>✅ Combine tool groups<br/>
147+
✅ Add individual tools<br/>
148+
❌ Overrides Pro eligibility</p>
149+
<br/>
150+
<code>GROUPS="browser"</code><br/>
151+
<code>TOOLS="scrape_as_html"</code>
152+
</td>
141153
</tr>
142154
</table>
143155
</div>
144156

145-
> **💡 Note:** Pro mode is **not included** in the free tier and incurs additional charges based on usage.
157+
> **💡 Note:** Pro mode is **not included** in the free tier and incurs
158+
> additional charges based on usage.
159+
160+
---
161+
162+
## 🧠 Advanced Tool Selection
163+
164+
- `GROUPS` lets you enable curated tool bundles. Use comma-separated group
165+
IDs such as `ecommerce,browser`.
166+
- `TOOLS` adds explicit tool names on top of the selected groups.
167+
- Mode priority: `PRO_MODE=true` (all tools) → `GROUPS` / `TOOLS`
168+
(whitelist) → default rapid mode (base toolkit).
169+
- Base tools always enabled: `search_engine`, `search_engine_batch`,
170+
`scrape_as_markdown`, `scrape_batch`.
171+
- Group ID `custom` is reserved; use `TOOLS` for bespoke picks.
172+
173+
174+
<table>
175+
<tr>
176+
<th align="left">Group ID</th>
177+
<th align="left">Description</th>
178+
<th align="left">Featured tools</th>
179+
</tr>
180+
<tr>
181+
<td><code>ecommerce</code></td>
182+
<td>Retail and marketplace datasets</td>
183+
<td><code>web_data_amazon_product</code>,
184+
<code>web_data_walmart_product</code>,
185+
<code>web_data_google_shopping</code></td>
186+
</tr>
187+
<tr>
188+
<td><code>social</code></td>
189+
<td>Social, community, and creator insights</td>
190+
<td><code>web_data_linkedin_posts</code>,
191+
<code>web_data_tiktok_posts</code>,
192+
<code>web_data_youtube_videos</code></td>
193+
</tr>
194+
<tr>
195+
<td><code>browser</code></td>
196+
<td>Bright Data Scraping Browser automation tools</td>
197+
<td><code>scraping_browser_snapshot</code>,
198+
<code>scraping_browser_click_ref</code>,
199+
<code>scraping_browser_screenshot</code></td>
200+
</tr>
201+
<tr>
202+
<td><code>business</code></td>
203+
<td>Company, property, and finance intelligence</td>
204+
<td><code>web_data_crunchbase_company</code>,
205+
<code>web_data_yahoo_finance_business</code>,
206+
<code>web_data_zillow_properties_listing</code></td>
207+
</tr>
208+
<tr>
209+
<td><code>research</code></td>
210+
<td>App store, news, and developer feeds</td>
211+
<td><code>web_data_google_play_store</code>,
212+
<code>web_data_apple_app_store</code>,
213+
<code>web_data_reuter_news</code></td>
214+
</tr>
215+
<tr>
216+
<td><code>advanced_scraping</code></td>
217+
<td>Batch and AI-assisted extraction helpers</td>
218+
<td><code>search_engine_batch</code>,
219+
<code>scrape_batch</code>,
220+
<code>extract</code></td>
221+
</tr>
222+
</table>
223+
224+
### Claude Desktop example
225+
226+
```json
227+
{
228+
"mcpServers": {
229+
"Bright Data": {
230+
"command": "npx",
231+
"args": ["@brightdata/mcp"],
232+
"env": {
233+
"API_TOKEN": "<your-api-token-here>",
234+
"GROUPS": "browser,advanced_scraping",
235+
"TOOLS": "extract"
236+
}
237+
}
238+
}
239+
}
240+
```
146241

147242
---
148243

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@
3737
"server.js",
3838
"browser_tools.js",
3939
"browser_session.js",
40-
"aria_snapshot_filter.js"
40+
"aria_snapshot_filter.js",
41+
"tool_groups.js"
4142
],
4243
"mcpName": "io.github.brightdata/brightdata-mcp"
4344
}

server.js

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {FastMCP} from 'fastmcp';
44
import {z} from 'zod';
55
import axios from 'axios';
66
import {tools as browser_tools} from './browser_tools.js';
7+
import {GROUPS} from './tool_groups.js';
78
import {createRequire} from 'node:module';
89
const require = createRequire(import.meta.url);
910
const package_json = require('./package.json');
@@ -13,6 +14,29 @@ const browser_zone = process.env.BROWSER_ZONE || 'mcp_browser';
1314
const pro_mode = process.env.PRO_MODE === 'true';
1415
const pro_mode_tools = ['search_engine', 'scrape_as_markdown',
1516
'search_engine_batch', 'scrape_batch'];
17+
const tool_groups = process.env.GROUPS ?
18+
process.env.GROUPS.split(',').map(g=>g.trim().toLowerCase())
19+
.filter(Boolean) : [];
20+
const custom_tools = process.env.TOOLS ?
21+
process.env.TOOLS.split(',').map(t=>t.trim()).filter(Boolean) : [];
22+
23+
function build_allowed_tools(groups = [], custom_tools = []){
24+
const allowed = new Set();
25+
for (const group_id of groups)
26+
{
27+
const group = Object.values(GROUPS)
28+
.find(g=>g.id===group_id);
29+
if (!group)
30+
continue;
31+
for (const tool of group.tools)
32+
allowed.add(tool);
33+
}
34+
for (const tool of custom_tools)
35+
allowed.add(tool);
36+
return allowed;
37+
}
38+
39+
const allowed_tools = build_allowed_tools(tool_groups, custom_tools);
1640
function parse_rate_limit(rate_limit_str) {
1741
if (!rate_limit_str)
1842
return null;
@@ -49,7 +73,8 @@ function check_rate_limit(){
4973
const now = Date.now();
5074
const window_start = now - rate_limit_config.window;
5175

52-
debug_stats.call_timestamps = debug_stats.call_timestamps.filter(timestamp=>timestamp>window_start);
76+
debug_stats.call_timestamps = debug_stats.call_timestamps
77+
.filter(timestamp=>timestamp>window_start);
5378

5479
if (debug_stats.call_timestamps.length>=rate_limit_config.limit)
5580
throw new Error(`Rate limit exceeded: ${rate_limit_config.display}`);
@@ -126,9 +151,21 @@ let server = new FastMCP({
126151
let debug_stats = {tool_calls: {}, session_calls: 0, call_timestamps: []};
127152

128153
const addTool = (tool) => {
129-
if (!pro_mode && !pro_mode_tools.includes(tool.name))
154+
if (pro_mode)
155+
{
156+
server.addTool(tool);
130157
return;
131-
server.addTool(tool);
158+
}
159+
160+
if (allowed_tools.size>0)
161+
{
162+
if (allowed_tools.has(tool.name))
163+
server.addTool(tool);
164+
return;
165+
}
166+
167+
if (pro_mode_tools.includes(tool.name))
168+
server.addTool(tool);
132169
};
133170

134171
addTool({

server.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,20 @@
4444
"isRequired": false,
4545
"isSecret": false,
4646
"format": "boolean"
47+
},
48+
{
49+
"name": "GROUPS",
50+
"description": "Comma-separated tool group IDs (e.g., 'ecommerce,browser')",
51+
"isRequired": false,
52+
"isSecret": false,
53+
"format": "string"
54+
},
55+
{
56+
"name": "TOOLS",
57+
"description": "Comma-separated tool names to enable",
58+
"isRequired": false,
59+
"isSecret": false,
60+
"format": "string"
4761
}
4862
]
4963
}

tool_groups.js

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
'use strict'; /*jslint node:true es9:true*/
2+
3+
const base_tools = ['search_engine', 'scrape_as_markdown'];
4+
5+
export const GROUPS = {
6+
ECOMMERCE: {
7+
id: 'ecommerce',
8+
name: 'E-commerce',
9+
description: 'Retail and marketplace datasets for product intel.',
10+
tools: [
11+
...base_tools,
12+
'web_data_amazon_product',
13+
'web_data_amazon_product_reviews',
14+
'web_data_amazon_product_search',
15+
'web_data_walmart_product',
16+
'web_data_walmart_seller',
17+
'web_data_ebay_product',
18+
'web_data_homedepot_products',
19+
'web_data_zara_products',
20+
'web_data_etsy_products',
21+
'web_data_bestbuy_products',
22+
'web_data_google_shopping',
23+
],
24+
},
25+
SOCIAL_MEDIA: {
26+
id: 'social',
27+
name: 'Social Media',
28+
description: 'Social networks, UGC platforms, and creator insights.',
29+
tools: [
30+
...base_tools,
31+
'web_data_linkedin_person_profile',
32+
'web_data_linkedin_company_profile',
33+
'web_data_linkedin_job_listings',
34+
'web_data_linkedin_posts',
35+
'web_data_linkedin_people_search',
36+
'web_data_instagram_profiles',
37+
'web_data_instagram_posts',
38+
'web_data_instagram_reels',
39+
'web_data_instagram_comments',
40+
'web_data_facebook_posts',
41+
'web_data_facebook_marketplace_listings',
42+
'web_data_facebook_company_reviews',
43+
'web_data_facebook_events',
44+
'web_data_tiktok_profiles',
45+
'web_data_tiktok_posts',
46+
'web_data_tiktok_shop',
47+
'web_data_tiktok_comments',
48+
'web_data_x_posts',
49+
'web_data_youtube_profiles',
50+
'web_data_youtube_comments',
51+
'web_data_youtube_videos',
52+
'web_data_reddit_posts',
53+
],
54+
},
55+
BROWSER: {
56+
id: 'browser',
57+
name: 'Browser Automation',
58+
description: 'Bright Data Scraping Browser tools for automation.',
59+
tools: [
60+
...base_tools,
61+
'scraping_browser_navigate',
62+
'scraping_browser_go_back',
63+
'scraping_browser_go_forward',
64+
'scraping_browser_snapshot',
65+
'scraping_browser_click_ref',
66+
'scraping_browser_type_ref',
67+
'scraping_browser_screenshot',
68+
'scraping_browser_network_requests',
69+
'scraping_browser_wait_for_ref',
70+
'scraping_browser_get_text',
71+
'scraping_browser_get_html',
72+
'scraping_browser_scroll',
73+
'scraping_browser_scroll_to_ref',
74+
],
75+
},
76+
FINANCE: {
77+
id: 'finance',
78+
name: 'Finance Intelligence',
79+
description: 'Company, financial, and location intelligence datasets.',
80+
tools: [
81+
...base_tools,
82+
'web_data_yahoo_finance_business',
83+
],
84+
},
85+
BUSINESS: {
86+
id: 'business',
87+
name: 'Business Intelligence',
88+
description: 'Company, and location intelligence datasets.',
89+
tools: [
90+
...base_tools,
91+
'web_data_crunchbase_company',
92+
'web_data_zoominfo_company_profile',
93+
'web_data_google_maps_reviews',
94+
'web_data_zillow_properties_listing',
95+
'web_data_booking_hotel_listings',
96+
],
97+
},
98+
RESEARCH: {
99+
id: 'research',
100+
name: 'Research',
101+
description: 'App stores, news, and developer data feeds.',
102+
tools: [
103+
...base_tools,
104+
'web_data_github_repository_file',
105+
'web_data_reuter_news',
106+
],
107+
},
108+
APP_STORES: {
109+
id: 'app_stores',
110+
name: 'App stores',
111+
description: 'App stores.',
112+
tools: [
113+
...base_tools,
114+
'web_data_google_play_store',
115+
'web_data_apple_app_store',
116+
],
117+
},
118+
TRAVEL: {
119+
id: 'travel',
120+
name: 'Travel',
121+
description: 'Travel information.',
122+
tools: [
123+
...base_tools,
124+
'web_data_booking_hotel_listings',
125+
],
126+
},
127+
ADVANCED_SCRAPING: {
128+
id: 'advanced_scraping',
129+
name: 'Advanced Scraping',
130+
description: 'Higher-throughput scraping utilities and batch helpers.',
131+
tools: [
132+
...base_tools,
133+
'search_engine_batch',
134+
'scrape_batch',
135+
'scrape_as_html',
136+
'extract',
137+
'session_stats',
138+
],
139+
},
140+
CUSTOM: {
141+
id: 'custom',
142+
name: 'Custom',
143+
description: 'Placeholder for user-defined tool selections.',
144+
tools: [...base_tools],
145+
},
146+
};
147+
148+
export const get_all_group_ids = ()=>{
149+
return Object.values(GROUPS)
150+
.map(group=>group.id)
151+
.filter(id=>id!=='custom');
152+
};
153+
154+
export const get_total_tool_count = ()=>{
155+
const all_tools = new Set();
156+
for (let group of Object.values(GROUPS))
157+
for (let tool of group.tools)
158+
all_tools.add(tool);
159+
return all_tools.size;
160+
};
161+
162+
export {base_tools};

0 commit comments

Comments
 (0)