@brave/brave-search-mcp-server 2.0.80 → 2.0.81

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # Brave Search MCP Server
2
2
 
3
- An MCP server implementation that integrates the Brave Search API, providing comprehensive search capabilities including web search, local business search, image search, video search, news search, and AI-powered summarization. This project supports both STDIO and HTTP transports, with STDIO as the default mode.
3
+ An MCP server implementation that integrates the Brave Search API, providing comprehensive search capabilities including web search, local business search, place search, image search, video search, news search, LLM context, and AI-powered summarization. This project supports both STDIO and HTTP transports, with STDIO as the default mode.
4
4
 
5
5
  [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/brave/brave-search-mcp-server)
6
6
 
@@ -98,6 +98,63 @@ Generates AI-powered summaries from web search results using Brave's summarizati
98
98
 
99
99
  **Usage:** First perform a web search with `summary: true`, then use the returned summary key with this tool.
100
100
 
101
+ ### Place Search (`brave_place_search`)
102
+ Searches for points of interest (POIs) in a specified geographic area using Brave's Place Search API. Returns rich, structured place data including name, address, opening hours, contact info, ratings, photos, categories, and timezone.
103
+
104
+ **Parameters:**
105
+ - `query` (string, optional): Query string used to refine the POI search (max 400 chars, 50 words). When omitted, returns general points of interest in the supplied area.
106
+ - `latitude` (number, optional): Latitude of the search center (-90 to 90). Typically paired with `longitude`.
107
+ - `longitude` (number, optional): Longitude of the search center (-180 to 180). Typically paired with `latitude`.
108
+ - `location` (string, optional): Location string used as an alternative to `latitude`/`longitude`. For US locations prefer the form `<city> <state> <country name>` (e.g., `san francisco ca united states`); for non-US locations use `<city> <country name>` (e.g., `tokyo japan`).
109
+ - `radius` (number, optional): Search radius around the supplied coordinates, in meters. If omitted, the search is performed globally.
110
+ - `count` (number, optional): Number of results to return (1-50, default 20).
111
+ - `country` (string, optional): Two-letter country code (default `US`).
112
+ - `search_lang` (string, optional): Search language (default `en`).
113
+ - `ui_lang` (string, optional): UI language (default `en-US`).
114
+ - `units` (string, optional): Distance units (`metric` or `imperial`, default `metric`).
115
+ - `safesearch` (string, optional): Safe search level (`off`, `moderate`, `strict`, default `strict`).
116
+ - `spellcheck` (boolean, optional): Whether to spellcheck the query (default `true`).
117
+ - `geoloc` (string, optional): Optional geolocation token used to refine results.
118
+
119
+ **Optional request headers:**
120
+ - `api-version` (string, optional): Brave API version (`YYYY-MM-DD`)
121
+ - `accept` (string, optional): Response media type (`application/json` or `*/*`)
122
+ - `cache-control` (string, optional): Use `no-cache` to request fresh content
123
+ - `user-agent` (string, optional): User agent originating the request
124
+
125
+ ### LLM Context (`brave_llm_context`)
126
+ Retrieves pre-extracted web content optimized for AI agents, LLM grounding, and RAG pipelines.
127
+
128
+ **Parameters:**
129
+ - `query` (string, required): Search query (max 400 chars, 50 words)
130
+ - `country` (string, optional): Search country code
131
+ - `search_lang` (string, optional): Search language code
132
+ - `count` (number, optional): Maximum number of search results considered (1-50)
133
+ - `spellcheck` (boolean, optional): Enable spell checking
134
+ - `maximum_number_of_urls` (number, optional): Maximum number of URLs to include (1-50)
135
+ - `maximum_number_of_tokens` (number, optional): Approximate maximum number of context tokens (1024-32768)
136
+ - `maximum_number_of_snippets` (number, optional): Maximum number of snippets to include (1-256)
137
+ - `context_threshold_mode` (string, optional): Threshold mode ("disabled", "strict", "lenient", "balanced")
138
+ - `maximum_number_of_tokens_per_url` (number, optional): Maximum tokens per URL (512-8192)
139
+ - `maximum_number_of_snippets_per_url` (number, optional): Maximum snippets per URL (1-100)
140
+ - `goggles` (string or array, optional): Goggle URL or definition for custom re-ranking
141
+ - `freshness` (string, optional): Time filter ("pd", "pw", "pm", "py", or date range)
142
+ - `enable_local` (boolean, optional): Enable local recall
143
+ - `enable_source_metadata` (boolean, optional): Include source metadata enrichment
144
+
145
+ **Optional request headers:**
146
+ - `x-loc-lat` (number, optional): Client latitude (-90 to 90)
147
+ - `x-loc-long` (number, optional): Client longitude (-180 to 180)
148
+ - `x-loc-city` (string, optional): Client city name
149
+ - `x-loc-state` (string, optional): Client state or region code
150
+ - `x-loc-state-name` (string, optional): Client state or region name
151
+ - `x-loc-country` (string, optional): Client country code
152
+ - `x-loc-postal-code` (string, optional): Client postal code
153
+ - `api-version` (string, optional): Brave API version (`YYYY-MM-DD`)
154
+ - `accept` (string, optional): Response media type ("application/json" or "*/*")
155
+ - `cache-control` (string, optional): Use `no-cache` to request fresh content
156
+ - `user-agent` (string, optional): User agent originating the request
157
+
101
158
  ## Configuration
102
159
 
103
160
  ### Getting an API Key
@@ -117,8 +174,8 @@ The server supports the following environment variables:
117
174
  - `BRAVE_MCP_PORT`: HTTP server port (default: 8000)
118
175
  - `BRAVE_MCP_HOST`: HTTP server host (default: "0.0.0.0")
119
176
  - `BRAVE_MCP_LOG_LEVEL`: Desired logging level("debug", "info", "notice", "warning", "error", "critical", "alert", or "emergency", default: "info")
120
- - `BRAVE_MCP_ENABLED_TOOLS`: When used, specifies a whitelist for supported tools
121
- - `BRAVE_MCP_DISABLED_TOOLS`: When used, specifies a blacklist for supported tools
177
+ - `BRAVE_MCP_ENABLED_TOOLS`: When used, specifies a space-separated whitelist for supported tools
178
+ - `BRAVE_MCP_DISABLED_TOOLS`: When used, specifies a space-separated blacklist for supported tools
122
179
  - `BRAVE_MCP_STATELESS`: HTTP stateless mode (default: "true"). When running on Amazon Bedrock Agentcore, set to "true".
123
180
 
124
181
  ### Command Line Options
@@ -139,14 +196,6 @@ Options:
139
196
 
140
197
  ## Installation
141
198
 
142
- ### Installing via Smithery
143
-
144
- To install Brave Search automatically via [Smithery](https://smithery.ai/server/brave):
145
-
146
- ```bash
147
- npx -y @smithery/cli install brave
148
- ```
149
-
150
199
  ### Usage with Claude Desktop
151
200
 
152
201
  Add this to your `claude_desktop_config.json`:
@@ -314,11 +363,6 @@ npx @modelcontextprotocol/inspector node dist/index.js
314
363
 
315
364
  STDIO is the default mode. For HTTP mode testing, add `--transport http` to the arguments in the Inspector UI.
316
365
 
317
- ### Testing via Smithery.AI
318
-
319
- 1. Establish and acquire a smithery.ai account and API key
320
- 2. Run `npm run install`, `npm run smithery:build`, and lastly `npm run smithery:dev` to begin testing
321
-
322
366
  ### Available Scripts
323
367
 
324
368
  - `npm run build`: Build the TypeScript project
@@ -329,8 +373,6 @@ STDIO is the default mode. For HTTP mode testing, add `--transport http` to the
329
373
 
330
374
  - `npm run inspector`: Launch an instance of MCP Inspector
331
375
  - `npm run inspector:stdio`: Launch a instance of MCP Inspector, configured for STDIO
332
- - `npm run smithery:build`: Build the project for smithery.ai
333
- - `npm run smithery:dev`: Launch the development environment for smithery.ai
334
376
 
335
377
  ### Docker Compose
336
378
 
@@ -8,6 +8,8 @@ const typeToPathMap = {
8
8
  videos: '/res/v1/videos/search',
9
9
  web: '/res/v1/web/search',
10
10
  summarizer: '/res/v1/summarizer/search',
11
+ llmContext: '/res/v1/llm/context',
12
+ placeSearch: '/res/v1/local/place_search',
11
13
  };
12
14
  const getDefaultRequestHeaders = () => {
13
15
  return {
@@ -25,9 +27,18 @@ const isValidGoggleURL = (url) => {
25
27
  return false;
26
28
  }
27
29
  };
28
- async function issueRequest(endpoint, parameters,
29
- // TODO (Sampson): Implement support for custom request headers (helpful for POIs, etc.)
30
- requestHeaders = {}) {
30
+ const normalizeGoggle = (value) => {
31
+ if (typeof value !== 'string')
32
+ return null;
33
+ const trimmed = value.trim();
34
+ if (trimmed.length === 0)
35
+ return null;
36
+ if (/^https?:\/\//i.test(trimmed)) {
37
+ return isValidGoggleURL(trimmed) ? trimmed : null;
38
+ }
39
+ return trimmed;
40
+ };
41
+ async function issueRequest(endpoint, parameters, requestHeaders = {}) {
31
42
  // TODO (Sampson): Improve rate-limit logic to support self-throttling and n-keys
32
43
  // checkRateLimit();
33
44
  // Determine URL, and setup parameters
@@ -49,11 +60,18 @@ requestHeaders = {}) {
49
60
  }
50
61
  // Handle `result_filter` parameter
51
62
  if (key === 'result_filter') {
52
- // Handle special behavior of 'summary' parameter:
53
- // Requires `result_filter` to be empty, or only contain 'summarizer'
54
- // see: https://bravesoftware.slack.com/archives/C01NNFM9XMM/p1751654841090929
63
+ /**
64
+ * Handle special behavior of 'summary' parameter:
65
+ * When 'summary' is true, we need to either set result_filter to
66
+ * 'summarizer', or leave it excluded entirely. This is due to a known
67
+ * bug in the now-deprecated Summarizer endpoint. Setting it to
68
+ * 'summarizer' will result in no web results being returned, which is
69
+ * not ideal. As such, we skip the parameter entirely.
70
+ * See https://github.com/brave/brave-search-mcp-server/issues/272 and
71
+ * https://bravesoftware.slack.com/archives/C01NNFM9XMM/p1751654841090929
72
+ */
55
73
  if ('summary' in parameters && parameters.summary === true) {
56
- queryParams.set(key, 'summarizer');
74
+ continue;
57
75
  }
58
76
  else if (Array.isArray(value) && value.length > 0) {
59
77
  queryParams.set(key, value.join(','));
@@ -62,23 +80,27 @@ requestHeaders = {}) {
62
80
  }
63
81
  // Handle `goggles` parameter(s)
64
82
  if (key === 'goggles') {
65
- if (typeof value === 'string') {
66
- queryParams.set(key, value);
67
- }
68
- else if (Array.isArray(value)) {
69
- for (const url of value.filter(isValidGoggleURL)) {
70
- queryParams.append(key, url);
83
+ const candidates = Array.isArray(value) ? value : [value];
84
+ for (const candidate of candidates) {
85
+ const normalized = normalizeGoggle(candidate);
86
+ if (normalized !== null) {
87
+ queryParams.append(key, normalized);
71
88
  }
72
89
  }
73
90
  continue;
74
91
  }
75
- if (value !== undefined) {
92
+ if (value !== undefined && value !== null) {
76
93
  queryParams.set(key === 'query' ? 'q' : key, value.toString());
77
94
  }
78
95
  }
79
96
  // Issue Request
80
97
  const urlWithParams = url.toString() + '?' + queryParams.toString();
81
- const headers = { ...getDefaultRequestHeaders(), ...requestHeaders };
98
+ const headers = new Headers(getDefaultRequestHeaders());
99
+ for (const [key, value] of Object.entries(requestHeaders)) {
100
+ if (value === undefined || value === null)
101
+ continue;
102
+ headers.set(key, String(value));
103
+ }
82
104
  const response = await fetch(urlWithParams, { headers });
83
105
  // Handle Error
84
106
  if (!response.ok) {
package/dist/config.js CHANGED
@@ -1,43 +1,18 @@
1
1
  import { LoggingLevelSchema } from '@modelcontextprotocol/sdk/types.js';
2
2
  import { Command } from 'commander';
3
3
  import dotenv from 'dotenv';
4
- import { z } from 'zod';
5
4
  import tools from './tools/index.js';
6
5
  dotenv.config({ debug: false, quiet: true });
7
- // Config schema for Smithery.ai
8
- export const configSchema = z.object({
9
- braveApiKey: z
10
- .string()
11
- .describe('Your API key')
12
- .default(process.env.BRAVE_API_KEY ?? ''),
13
- enabledTools: z
14
- .array(z.string())
15
- .describe('Enforces a tool whitelist (cannot be used with disabledTools)')
16
- .optional(),
17
- disabledTools: z
18
- .array(z.string())
19
- .describe('Enforces a tool blacklist (cannot be used with enabledTools)')
20
- .optional(),
21
- loggingLevel: z
22
- .enum([
23
- 'debug',
24
- 'error',
25
- 'info',
26
- 'notice',
27
- 'warning',
28
- 'critical',
29
- 'alert',
30
- 'emergency',
31
- ])
32
- .default('info')
33
- .describe('Desired logging level')
34
- .optional(),
35
- stateless: z
36
- .boolean()
37
- .default(false)
38
- .describe('Whether the server should be stateless')
39
- .optional(),
40
- });
6
+ function parseToolNameList(value) {
7
+ if (value == null)
8
+ return [];
9
+ if (Array.isArray(value))
10
+ return value.map((t) => t.trim()).filter((t) => t.length > 0);
11
+ return value
12
+ .trim()
13
+ .split(/\s+/)
14
+ .filter((t) => t.length > 0);
15
+ }
41
16
  const state = {
42
17
  transport: 'stdio',
43
18
  port: 8080,
@@ -69,14 +44,16 @@ export function getOptions() {
69
44
  const options = program.opts();
70
45
  const toolNames = Object.values(tools).map((tool) => tool.name);
71
46
  // Validate tool inclusion configuration
72
- const enabledTools = options.enabledTools.filter((t) => t.trim().length > 0);
73
- const disabledTools = options.disabledTools.filter((t) => t.trim().length > 0);
47
+ const enabledTools = parseToolNameList(options.enabledTools);
48
+ const disabledTools = parseToolNameList(options.disabledTools);
74
49
  if (enabledTools.length > 0 && disabledTools.length > 0) {
75
50
  console.error('Error: --enabled-tools and --disabled-tools cannot be used together');
76
51
  return false;
77
52
  }
78
- if ([...enabledTools, ...disabledTools].some((t) => t.trim().length > 0 && !toolNames.includes(t.trim()))) {
79
- console.error(`Invalid tool name used. Must be one of: ${toolNames.join(', ')}`);
53
+ const invalidToolNames = [...enabledTools, ...disabledTools].filter((t) => !toolNames.includes(t));
54
+ if (invalidToolNames.length > 0) {
55
+ console.error(`Invalid tool name(s) used: ${invalidToolNames.join(', ')}`);
56
+ console.error(`Valid tool names are: ${toolNames.join(', ')}`);
80
57
  return false;
81
58
  }
82
59
  // Validate all other options
@@ -110,13 +87,10 @@ export function getOptions() {
110
87
  state.port = options.port;
111
88
  state.host = options.host;
112
89
  state.loggingLevel = options.loggingLevel;
113
- state.enabledTools = options.enabledTools;
114
- state.disabledTools = options.disabledTools;
90
+ state.enabledTools = enabledTools;
91
+ state.disabledTools = disabledTools;
115
92
  state.stateless = options.stateless;
116
93
  state.ready = true;
117
94
  return options;
118
95
  }
119
- export function setOptions(options) {
120
- return Object.assign(state, options);
121
- }
122
96
  export default state;
package/dist/server.js CHANGED
@@ -2,11 +2,7 @@ import tools from './tools/index.js';
2
2
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
3
  import pkg from '../package.json' with { type: 'json' };
4
4
  import { isToolPermittedByUser } from './config.js';
5
- import { setOptions } from './config.js';
6
- export { configSchema } from './config.js';
7
- export default function createMcpServer(options) {
8
- if (options?.config)
9
- setOptions(options.config);
5
+ export default function createMcpServer() {
10
6
  const mcpServer = new McpServer({
11
7
  version: pkg.version,
12
8
  name: 'brave-search-mcp-server',
@@ -4,6 +4,8 @@ import VideoSearchTool from './videos/index.js';
4
4
  import ImageSearchTool from './images/index.js';
5
5
  import NewsSearchTool from './news/index.js';
6
6
  import SummarizerTool from './summarizer/index.js';
7
+ import LlmContextTool from './llm_context/index.js';
8
+ import PlaceSearchTool from './place_search/index.js';
7
9
  export default {
8
10
  WebSearchTool,
9
11
  LocalSearchTool,
@@ -11,4 +13,6 @@ export default {
11
13
  ImageSearchTool,
12
14
  NewsSearchTool,
13
15
  SummarizerTool,
16
+ LlmContextTool,
17
+ PlaceSearchTool,
14
18
  };
@@ -0,0 +1,51 @@
1
+ import { z } from 'zod';
2
+ import API from '../../BraveAPI/index.js';
3
+ import { RequestParamsSchema, RequestHeadersSchema, LlmContextInputSchema, } from './schemas/input.js';
4
+ import { LlmContextSearchApiResponseSchema } from './schemas/output.js';
5
+ export const name = 'brave_llm_context';
6
+ export const annotations = {
7
+ title: 'Brave LLM Context',
8
+ openWorldHint: true,
9
+ };
10
+ export const description = `
11
+ Retrieves pre-extracted, relevance-ranked web content using Brave's LLM Context API, optimized for AI agents, LLM grounding, and RAG pipelines. Unlike a traditional web search that returns links and short descriptions, this tool returns the actual substance of matching pages — text chunks, tables, code blocks, and structured data — so the model can reason over it directly.
12
+
13
+ When to use:
14
+ - Grounding answers in fresh, relevant web content (RAG)
15
+ - Giving an AI agent ready-to-use page content from a single search call
16
+ - Question answering and fact-checking against current sources
17
+ - Gathering source material for research without manually fetching pages
18
+ - When you need the contents of pages, not just titles, descriptions, and URLs
19
+
20
+ When relaying results in markdown-supporting environments, cite the source URLs from the "sources" map.
21
+ `.trim();
22
+ export const execute = async (params) => {
23
+ const parsedParams = RequestParamsSchema.parse(params);
24
+ const parsedHeaders = RequestHeadersSchema.parse(params);
25
+ const response = await API.issueRequest('llmContext', parsedParams, parsedHeaders);
26
+ const { success, data, error } = LlmContextSearchApiResponseSchema.safeParse(response);
27
+ const payload = success ? data : z.treeifyError(error);
28
+ return {
29
+ content: [{ type: 'text', text: JSON.stringify(payload) }],
30
+ isError: !success,
31
+ structuredContent: payload,
32
+ };
33
+ };
34
+ export const register = (mcpServer) => {
35
+ mcpServer.registerTool(name, {
36
+ title: name,
37
+ description: description,
38
+ inputSchema: LlmContextInputSchema.shape,
39
+ outputSchema: LlmContextSearchApiResponseSchema.shape,
40
+ annotations: annotations,
41
+ }, execute);
42
+ };
43
+ export default {
44
+ name,
45
+ description,
46
+ annotations,
47
+ inputSchema: LlmContextInputSchema.shape,
48
+ outputSchema: LlmContextSearchApiResponseSchema.shape,
49
+ execute,
50
+ register,
51
+ };
@@ -0,0 +1,228 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Keep up-to-date with documentation:
4
+ * https://api-dashboard.search.brave.com/api-reference/summarizer/llm_context/get
5
+ */
6
+ const CountryCodesSchema = z.enum([
7
+ 'AR',
8
+ 'AU',
9
+ 'AT',
10
+ 'BE',
11
+ 'BR',
12
+ 'CA',
13
+ 'CL',
14
+ 'DK',
15
+ 'FI',
16
+ 'FR',
17
+ 'DE',
18
+ 'GR',
19
+ 'HK',
20
+ 'IN',
21
+ 'ID',
22
+ 'IT',
23
+ 'JP',
24
+ 'KR',
25
+ 'MY',
26
+ 'MX',
27
+ 'NL',
28
+ 'NZ',
29
+ 'NO',
30
+ 'CN',
31
+ 'PL',
32
+ 'PT',
33
+ 'PH',
34
+ 'RU',
35
+ 'SA',
36
+ 'ZA',
37
+ 'ES',
38
+ 'SE',
39
+ 'CH',
40
+ 'TW',
41
+ 'TR',
42
+ 'GB',
43
+ 'US',
44
+ 'ALL',
45
+ ]);
46
+ const SearchLangCodesSchema = z.enum([
47
+ 'ar',
48
+ 'eu',
49
+ 'bn',
50
+ 'bg',
51
+ 'ca',
52
+ 'zh-hans',
53
+ 'zh-hant',
54
+ 'hr',
55
+ 'cs',
56
+ 'da',
57
+ 'nl',
58
+ 'en',
59
+ 'en-gb',
60
+ 'et',
61
+ 'fi',
62
+ 'fr',
63
+ 'gl',
64
+ 'de',
65
+ 'el',
66
+ 'gu',
67
+ 'he',
68
+ 'hi',
69
+ 'hu',
70
+ 'is',
71
+ 'it',
72
+ 'jp',
73
+ 'kn',
74
+ 'ko',
75
+ 'lv',
76
+ 'lt',
77
+ 'ms',
78
+ 'ml',
79
+ 'mr',
80
+ 'nb',
81
+ 'pl',
82
+ 'pt-br',
83
+ 'pt-pt',
84
+ 'pa',
85
+ 'ro',
86
+ 'ru',
87
+ 'sr',
88
+ 'sk',
89
+ 'sl',
90
+ 'es',
91
+ 'sv',
92
+ 'ta',
93
+ 'te',
94
+ 'th',
95
+ 'tr',
96
+ 'uk',
97
+ 'vi',
98
+ ]);
99
+ const FreshnessSchema = z
100
+ .union([
101
+ z.enum(['pd', 'pw', 'pm', 'py']),
102
+ z
103
+ .string()
104
+ .regex(/^\d{4}-\d{2}-\d{2}to\d{4}-\d{2}-\d{2}$/, "Use 'pd', 'pw', 'pm', 'py', or a custom range as YYYY-MM-DDtoYYYY-MM-DD."),
105
+ ])
106
+ .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.");
107
+ export const RequestParamsSchema = z.object({
108
+ query: z
109
+ .string()
110
+ .trim()
111
+ .min(1)
112
+ .max(400)
113
+ .refine((str) => str.split(/\s+/).length <= 50, 'Query cannot exceed 50 words')
114
+ .describe("The user's search query term. Query can not be empty. Maximum of 400 characters and 50 words in the query."),
115
+ country: CountryCodesSchema.describe('The search query country, where the results come from. The country string is limited to 2 character country codes of supported countries.').optional(),
116
+ search_lang: SearchLangCodesSchema.describe('The search language preference. The 2 or more character language code for which the search results are provided.').optional(),
117
+ count: z
118
+ .number()
119
+ .int()
120
+ .min(1)
121
+ .max(50)
122
+ .describe('The maximum number of search results considered to select the LLM context data. The default is 20 and the maximum is 50.')
123
+ .optional(),
124
+ spellcheck: z.boolean().describe('Whether to enable spellcheck on the query.').optional(),
125
+ maximum_number_of_urls: z
126
+ .number()
127
+ .int()
128
+ .min(1)
129
+ .max(50)
130
+ .describe('Maximum number of different URLs to include in LLM context.')
131
+ .optional(),
132
+ maximum_number_of_tokens: z
133
+ .number()
134
+ .int()
135
+ .min(1024)
136
+ .max(32768)
137
+ .describe('Approximate maximum number of tokens to include in context. The default is 8192 and maximum is 32768.')
138
+ .optional(),
139
+ maximum_number_of_snippets: z
140
+ .number()
141
+ .int()
142
+ .min(1)
143
+ .max(256)
144
+ .describe('Maximum number of different snippets (or chunks of text) to include in LLM context. The default is 50 and maximum is 256.')
145
+ .optional(),
146
+ context_threshold_mode: z
147
+ .enum(['disabled', 'strict', 'lenient', 'balanced'])
148
+ .describe('The mode to use to determine the threshold for including content in context. Default is balanced.')
149
+ .optional(),
150
+ maximum_number_of_tokens_per_url: z
151
+ .number()
152
+ .int()
153
+ .min(512)
154
+ .max(8192)
155
+ .describe('Maximum number of tokens to include per URL. The default is 4096 and maximum is 8192.')
156
+ .optional(),
157
+ maximum_number_of_snippets_per_url: z
158
+ .number()
159
+ .int()
160
+ .min(1)
161
+ .max(100)
162
+ .describe('Maximum number of snippets to include per URL. The default is 50 and maximum is 100.')
163
+ .optional(),
164
+ goggles: z
165
+ .union([z.string(), z.array(z.string())])
166
+ .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. Multiple goggle URLs and/or definitions can be provided in an array. For more details, refer to the Goggles repository (i.e., https://github.com/brave/goggles-quickstart).")
167
+ .optional(),
168
+ freshness: FreshnessSchema.optional(),
169
+ enable_local: z
170
+ .boolean()
171
+ .describe('Whether to enable local recall. Not setting this value means auto-detect and uses local recall if any of the localization headers are provided.')
172
+ .optional(),
173
+ enable_source_metadata: z
174
+ .boolean()
175
+ .describe('Enable source metadata enrichment (site_name, favicon) in the sources attribute of the response.')
176
+ .optional(),
177
+ });
178
+ export const RequestHeadersSchema = z.object({
179
+ 'x-loc-lat': z
180
+ .number()
181
+ .min(-90)
182
+ .max(90)
183
+ .describe("The latitude of the client's geographical location in degrees, to provide relevant local results. The latitude must be greater than or equal to -90.0 degrees and less than or equal to +90.0 degrees.")
184
+ .optional(),
185
+ 'x-loc-long': z
186
+ .number()
187
+ .min(-180)
188
+ .max(180)
189
+ .describe("The longitude of the client's geographical location in degrees, to provide relevant local results. The longitude must be greater than or equal to -180.0 and less than or equal to +180.0 degrees.")
190
+ .optional(),
191
+ 'x-loc-city': z.string().describe('The generic name of the client city').optional(),
192
+ 'x-loc-state': z
193
+ .string()
194
+ .max(3)
195
+ .describe("A code which could be up to three characters, that represent the client's state/region. The region is the first-level subdivision (the broadest or least specific) of the ISO 3166-2 code.")
196
+ .optional(),
197
+ 'x-loc-state-name': z
198
+ .string()
199
+ .describe('The name of the client’s state/region. The region is the first-level subdivision (the broadest or least specific) of the ISO 3166-2 code.')
200
+ .optional(),
201
+ 'x-loc-country': z
202
+ .string()
203
+ .length(2)
204
+ .describe('The two letter country code for the client’s country. For a list of country codes, see ISO 3166-1 alpha-2')
205
+ .optional(),
206
+ 'x-loc-postal-code': z.string().describe('The client’s postal code').optional(),
207
+ 'api-version': z
208
+ .string()
209
+ .regex(/^\d{4}-\d{2}-\d{2}$/)
210
+ .describe('The API version to use. This is denoted by the format YYYY-MM-DD. Default is the latest that is available. Read more about API versioning at https://api-dashboard.search.brave.com/documentation/guides/versioning.')
211
+ .optional(),
212
+ accept: z
213
+ .enum(['application/json', '*/*'])
214
+ .describe('The default supported media type is application/json.')
215
+ .optional(),
216
+ 'cache-control': z
217
+ .literal('no-cache')
218
+ .describe('Brave Search will return cached content by default. To prevent caching set the Cache-Control header to no-cache. This is currently done as best effort.')
219
+ .optional(),
220
+ 'user-agent': z
221
+ .string()
222
+ .describe('The user agent originating the request. Brave search can utilize the user agent to provide a different experience depending on the device as described by the string. The user agent should follow the commonly used browser agent strings on each platform. For more information on curating user agents, see RFC 9110.')
223
+ .optional(),
224
+ });
225
+ export const LlmContextInputSchema = z.object({
226
+ ...RequestParamsSchema.shape,
227
+ ...RequestHeadersSchema.shape,
228
+ });