@brave/brave-search-mcp-server 1.3.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/LICENSE +22 -0
- package/README.md +305 -0
- package/dist/BraveAPI/index.js +94 -0
- package/dist/BraveAPI/types.js +1 -0
- package/dist/config.js +44 -0
- package/dist/constants.js +4 -0
- package/dist/helpers.js +10 -0
- package/dist/index.js +26 -0
- package/dist/protocols/http.js +41 -0
- package/dist/protocols/index.js +2 -0
- package/dist/protocols/stdio.js +8 -0
- package/dist/server.js +16 -0
- package/dist/tools/images/index.js +50 -0
- package/dist/tools/images/params.js +38 -0
- package/dist/tools/images/types.js +1 -0
- package/dist/tools/index.js +14 -0
- package/dist/tools/local/index.js +136 -0
- package/dist/tools/local/params.js +7 -0
- package/dist/tools/local/types.js +1 -0
- package/dist/tools/news/index.js +53 -0
- package/dist/tools/news/params.js +64 -0
- package/dist/tools/news/types.js +1 -0
- package/dist/tools/summarizer/index.js +89 -0
- package/dist/tools/summarizer/params.js +60 -0
- package/dist/tools/summarizer/types.js +1 -0
- package/dist/tools/videos/index.js +37 -0
- package/dist/tools/videos/params.js +55 -0
- package/dist/tools/videos/types.js +1 -0
- package/dist/tools/web/index.js +140 -0
- package/dist/tools/web/params.js +220 -0
- package/dist/tools/web/types.js +1 -0
- package/dist/utils.js +26 -0
- package/package.json +46 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export const params = z.object({
|
|
3
|
+
query: z
|
|
4
|
+
.string()
|
|
5
|
+
.max(400)
|
|
6
|
+
.refine((str) => str.split(/\s+/).length <= 50, 'Query cannot exceed 50 words')
|
|
7
|
+
.describe('Search query (max 400 chars, 50 words)'),
|
|
8
|
+
country: z
|
|
9
|
+
.enum([
|
|
10
|
+
'ALL',
|
|
11
|
+
'AR',
|
|
12
|
+
'AU',
|
|
13
|
+
'AT',
|
|
14
|
+
'BE',
|
|
15
|
+
'BR',
|
|
16
|
+
'CA',
|
|
17
|
+
'CL',
|
|
18
|
+
'DK',
|
|
19
|
+
'FI',
|
|
20
|
+
'FR',
|
|
21
|
+
'DE',
|
|
22
|
+
'HK',
|
|
23
|
+
'IN',
|
|
24
|
+
'ID',
|
|
25
|
+
'IT',
|
|
26
|
+
'JP',
|
|
27
|
+
'KR',
|
|
28
|
+
'MY',
|
|
29
|
+
'MX',
|
|
30
|
+
'NL',
|
|
31
|
+
'NZ',
|
|
32
|
+
'NO',
|
|
33
|
+
'CN',
|
|
34
|
+
'PL',
|
|
35
|
+
'PT',
|
|
36
|
+
'PH',
|
|
37
|
+
'RU',
|
|
38
|
+
'SA',
|
|
39
|
+
'ZA',
|
|
40
|
+
'ES',
|
|
41
|
+
'SE',
|
|
42
|
+
'CH',
|
|
43
|
+
'TW',
|
|
44
|
+
'TR',
|
|
45
|
+
'GB',
|
|
46
|
+
'US',
|
|
47
|
+
])
|
|
48
|
+
.default('US')
|
|
49
|
+
.describe('Search query country, where the results come from. The country string is limited to 2 character country codes of supported countries.')
|
|
50
|
+
.optional(),
|
|
51
|
+
search_lang: z
|
|
52
|
+
.enum([
|
|
53
|
+
'ar',
|
|
54
|
+
'eu',
|
|
55
|
+
'bn',
|
|
56
|
+
'bg',
|
|
57
|
+
'ca',
|
|
58
|
+
'zh-hans',
|
|
59
|
+
'zh-hant',
|
|
60
|
+
'hr',
|
|
61
|
+
'cs',
|
|
62
|
+
'da',
|
|
63
|
+
'nl',
|
|
64
|
+
'en',
|
|
65
|
+
'en-gb',
|
|
66
|
+
'et',
|
|
67
|
+
'fi',
|
|
68
|
+
'fr',
|
|
69
|
+
'gl',
|
|
70
|
+
'de',
|
|
71
|
+
'gu',
|
|
72
|
+
'he',
|
|
73
|
+
'hi',
|
|
74
|
+
'hu',
|
|
75
|
+
'is',
|
|
76
|
+
'it',
|
|
77
|
+
'jp',
|
|
78
|
+
'kn',
|
|
79
|
+
'ko',
|
|
80
|
+
'lv',
|
|
81
|
+
'lt',
|
|
82
|
+
'ms',
|
|
83
|
+
'ml',
|
|
84
|
+
'mr',
|
|
85
|
+
'nb',
|
|
86
|
+
'pl',
|
|
87
|
+
'pt-br',
|
|
88
|
+
'pt-pt',
|
|
89
|
+
'pa',
|
|
90
|
+
'ro',
|
|
91
|
+
'ru',
|
|
92
|
+
'sr',
|
|
93
|
+
'sk',
|
|
94
|
+
'sl',
|
|
95
|
+
'es',
|
|
96
|
+
'sv',
|
|
97
|
+
'ta',
|
|
98
|
+
'te',
|
|
99
|
+
'th',
|
|
100
|
+
'tr',
|
|
101
|
+
'uk',
|
|
102
|
+
'vi',
|
|
103
|
+
])
|
|
104
|
+
.default('en')
|
|
105
|
+
.describe('Search language preference. The 2 or more character language code for which the search results are provided.')
|
|
106
|
+
.optional(),
|
|
107
|
+
ui_lang: z
|
|
108
|
+
.enum([
|
|
109
|
+
'es-AR',
|
|
110
|
+
'en-AU',
|
|
111
|
+
'de-AT',
|
|
112
|
+
'nl-BE',
|
|
113
|
+
'fr-BE',
|
|
114
|
+
'pt-BR',
|
|
115
|
+
'en-CA',
|
|
116
|
+
'fr-CA',
|
|
117
|
+
'es-CL',
|
|
118
|
+
'da-DK',
|
|
119
|
+
'fi-FI',
|
|
120
|
+
'fr-FR',
|
|
121
|
+
'de-DE',
|
|
122
|
+
'zh-HK',
|
|
123
|
+
'en-IN',
|
|
124
|
+
'en-ID',
|
|
125
|
+
'it-IT',
|
|
126
|
+
'ja-JP',
|
|
127
|
+
'ko-KR',
|
|
128
|
+
'en-MY',
|
|
129
|
+
'es-MX',
|
|
130
|
+
'nl-NL',
|
|
131
|
+
'en-NZ',
|
|
132
|
+
'no-NO',
|
|
133
|
+
'zh-CN',
|
|
134
|
+
'pl-PL',
|
|
135
|
+
'en-PH',
|
|
136
|
+
'ru-RU',
|
|
137
|
+
'en-ZA',
|
|
138
|
+
'es-ES',
|
|
139
|
+
'sv-SE',
|
|
140
|
+
'fr-CH',
|
|
141
|
+
'de-CH',
|
|
142
|
+
'zh-TW',
|
|
143
|
+
'tr-TR',
|
|
144
|
+
'en-GB',
|
|
145
|
+
'en-US',
|
|
146
|
+
'es-US',
|
|
147
|
+
])
|
|
148
|
+
.default('en-US')
|
|
149
|
+
.describe('The language of the UI. The 2 or more character language code for which the search results are provided.')
|
|
150
|
+
.optional(),
|
|
151
|
+
count: z
|
|
152
|
+
.number()
|
|
153
|
+
.int()
|
|
154
|
+
.min(1)
|
|
155
|
+
.max(20)
|
|
156
|
+
.default(10)
|
|
157
|
+
.describe('Number of results (1-20, default 10). Applies only to web search results (i.e., has no effect on locations, news, videos, etc.)')
|
|
158
|
+
.optional(),
|
|
159
|
+
offset: z
|
|
160
|
+
.number()
|
|
161
|
+
.int()
|
|
162
|
+
.min(0)
|
|
163
|
+
.max(9)
|
|
164
|
+
.default(0)
|
|
165
|
+
.describe('Pagination offset (max 9, default 0)')
|
|
166
|
+
.optional(),
|
|
167
|
+
safesearch: z
|
|
168
|
+
.enum(['off', 'moderate', 'strict'])
|
|
169
|
+
.default('moderate')
|
|
170
|
+
.describe("Filters search results for adult content. The following values are supported: 'off' - No filtering. 'moderate' - Filters explicit content (e.g., images and videos), but allows adult domains in search results. 'strict' - Drops all adult content from search results. The default value is 'moderate'.")
|
|
171
|
+
.optional(),
|
|
172
|
+
freshness: z
|
|
173
|
+
.enum(['pd', 'pw', 'pm', 'py', 'YYYY-MM-DDtoYYYY-MM-DD'])
|
|
174
|
+
.describe("Filters search results by when they were discovered. The following values are supported: 'pd' - Discovered within the last 24 hours. 'pw' - Discovered within the last 7 days. 'pm' - Discovered within the last 31 days. 'py' - Discovered within the last 365 days. 'YYYY-MM-DDtoYYYY-MM-DD' - Timeframe is also supported by specifying the date range e.g. 2022-04-01to2022-07-30.")
|
|
175
|
+
.optional(),
|
|
176
|
+
text_decorations: z
|
|
177
|
+
.boolean()
|
|
178
|
+
.default(true)
|
|
179
|
+
.describe('Whether display strings (e.g. result snippets) should include decoration markers (e.g. highlighting characters).')
|
|
180
|
+
.optional(),
|
|
181
|
+
spellcheck: z
|
|
182
|
+
.boolean()
|
|
183
|
+
.default(true)
|
|
184
|
+
.describe('Whether to spellcheck the provided query.')
|
|
185
|
+
.optional(),
|
|
186
|
+
result_filter: z
|
|
187
|
+
.array(z.enum([
|
|
188
|
+
'discussions',
|
|
189
|
+
'faq',
|
|
190
|
+
'infobox',
|
|
191
|
+
'news',
|
|
192
|
+
'query',
|
|
193
|
+
'summarizer',
|
|
194
|
+
'videos',
|
|
195
|
+
'web',
|
|
196
|
+
'summarizer',
|
|
197
|
+
'locations',
|
|
198
|
+
'rich',
|
|
199
|
+
]))
|
|
200
|
+
.default(['web', 'query'])
|
|
201
|
+
.describe("Result filter (default ['web', 'query'])")
|
|
202
|
+
.optional(),
|
|
203
|
+
goggles: z
|
|
204
|
+
.array(z.string())
|
|
205
|
+
.describe("Goggles act as a custom re-ranking on top of Brave's search index. The parameter supports both a url where the Goggle is hosted or the definition of the Goggle. For more details, refer to the Goggles repository (i.e., https://github.com/brave/goggles-quickstart).")
|
|
206
|
+
.optional(),
|
|
207
|
+
units: z
|
|
208
|
+
.union([z.literal('metric'), z.literal('imperial')])
|
|
209
|
+
.describe('The measurement units. If not provided, units are derived from search country.')
|
|
210
|
+
.optional(),
|
|
211
|
+
extra_snippets: z
|
|
212
|
+
.boolean()
|
|
213
|
+
.describe('A snippet is an excerpt from a page you get as a result of the query, and extra_snippets allow you to get up to 5 additional, alternative excerpts. Only available under Free AI, Base AI, Pro AI, Base Data, Pro Data and Custom plans.')
|
|
214
|
+
.optional(),
|
|
215
|
+
summary: z
|
|
216
|
+
.boolean()
|
|
217
|
+
.describe('This parameter enables summary key generation in web search results. This is required for summarizer to be enabled.')
|
|
218
|
+
.optional(),
|
|
219
|
+
});
|
|
220
|
+
export default params;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { RATE_LIMIT } from './constants.js';
|
|
2
|
+
import { server } from './server.js';
|
|
3
|
+
let requestCount = {
|
|
4
|
+
second: 0,
|
|
5
|
+
month: 0,
|
|
6
|
+
lastReset: Date.now(),
|
|
7
|
+
};
|
|
8
|
+
export async function log(level, message) {
|
|
9
|
+
const time = new Date().toISOString();
|
|
10
|
+
await server.server.sendLoggingMessage({ level, data: { message, time } });
|
|
11
|
+
}
|
|
12
|
+
export function checkRateLimit() {
|
|
13
|
+
const now = Date.now();
|
|
14
|
+
if (now - requestCount.lastReset > 1000) {
|
|
15
|
+
requestCount.second = 0;
|
|
16
|
+
requestCount.lastReset = now;
|
|
17
|
+
}
|
|
18
|
+
if (requestCount.second >= RATE_LIMIT.perSecond || requestCount.month >= RATE_LIMIT.perMonth) {
|
|
19
|
+
throw new Error('Rate limit exceeded');
|
|
20
|
+
}
|
|
21
|
+
requestCount.second++;
|
|
22
|
+
requestCount.month++;
|
|
23
|
+
}
|
|
24
|
+
export function stringify(data, pretty = false) {
|
|
25
|
+
return pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);
|
|
26
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@brave/brave-search-mcp-server",
|
|
3
|
+
"version": "1.3.1",
|
|
4
|
+
"description": "MCP server for Brave Search. Uses the Brave Search API to return results from the web, including ranked links, images, and videos, as well as AI summaries of pages, rich results, and more.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"api",
|
|
7
|
+
"brave",
|
|
8
|
+
"mcp",
|
|
9
|
+
"search"
|
|
10
|
+
],
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"author": "Brave Software, Inc. (https://brave.com)",
|
|
13
|
+
"homepage": "https://github.com/brave/brave-search-mcp-server",
|
|
14
|
+
"bugs": "https://github.com/brave/brave-search-mcp-server/issues",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/brave/brave-search-mcp-server.git"
|
|
18
|
+
},
|
|
19
|
+
"type": "module",
|
|
20
|
+
"bin": {
|
|
21
|
+
"brave-search-mcp-server": "dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"dist"
|
|
25
|
+
],
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsc && shx chmod +x dist/*.js",
|
|
28
|
+
"prepare": "npm run format && npm run build",
|
|
29
|
+
"watch": "tsc --watch",
|
|
30
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
31
|
+
"format:check": "prettier --check \"src/**/*.ts\""
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@modelcontextprotocol/sdk": "1.13.3",
|
|
35
|
+
"commander": "14.0.0",
|
|
36
|
+
"express": "5.1.0",
|
|
37
|
+
"zod": "3.25.67"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/express": "5.0.3",
|
|
41
|
+
"@types/node": "24.0.3",
|
|
42
|
+
"prettier": "3.6.2",
|
|
43
|
+
"shx": "0.4.0",
|
|
44
|
+
"typescript": "5.8.3"
|
|
45
|
+
}
|
|
46
|
+
}
|