API: tools/research
better-web-search-mcp / tools/research
tools/research#
Interfaces#
Citation#
Defined in: src/tools/research.ts:50
A span of a source page that supports the answer.
Properties#
| Property | Type | Description | Defined in |
|---|---|---|---|
citation | number | 1-based index into sources. | src/tools/research.ts:52 |
end | number | Character offset of the quote end. | src/tools/research.ts:62 |
quote | string | The supporting text, verbatim from the extracted content. | src/tools/research.ts:58 |
relevance | number | Relevance of the span to the question. Higher is stronger. | src/tools/research.ts:64 |
start | number | Character offset of the quote within that page’s extracted content. | src/tools/research.ts:60 |
title | string | The source title. | src/tools/research.ts:56 |
url | string | The source URL the span was taken from. | src/tools/research.ts:54 |
ResearchResponse#
Defined in: src/tools/research.ts:67
Properties#
| Property | Type | Description | Defined in |
|---|---|---|---|
answer | string | - | src/tools/research.ts:68 |
citations | Citation[] | The exact spans the answer was assembled from, so an agent can attribute a statement to a span rather than to a whole page. | src/tools/research.ts:75 |
evidence | { cited_spans: number; derivative_sources: number; independent_sources: number; query_term_coverage: number; sources_opened: number; } | Countable facts about the evidence behind the answer. Every field is something the server measured, not a judgement: there is no language model here to score truth or agreement, and an invented confidence number would be worse than none. An agent can use these to decide whether to research further. | src/tools/research.ts:84 |
evidence.cited_spans | number | Number of cited spans in citations. | src/tools/research.ts:102 |
evidence.derivative_sources | number | Pages that duplicate another page’s content or host. | src/tools/research.ts:94 |
evidence.independent_sources | number | Distinct content clusters among those pages. Syndicated reprints and multiple pages from one host collapse into a single cluster, so this is the number of genuinely separate accounts. | src/tools/research.ts:92 |
evidence.query_term_coverage | number | Fraction of the question’s content words that appear in the cited passages, 0..1. Low values mean the citations may not address the question, not that the answer is wrong. | src/tools/research.ts:100 |
evidence.sources_opened | number | Pages actually opened and extracted. | src/tools/research.ts:86 |
extraction_stats | { avgConfidence: number; method_counts: Record<string, number>; } | - | src/tools/research.ts:104 |
extraction_stats.avgConfidence | number | - | src/tools/research.ts:106 |
extraction_stats.method_counts | Record<string, number> | - | src/tools/research.ts:105 |
queries_used | string[] | - | src/tools/research.ts:70 |
sources | SearchSource[] | - | src/tools/research.ts:69 |
SourceIndependence#
Defined in: src/tools/research.ts:40
Whether a source is an independent account or a copy of another.
Properties#
| Property | Type | Description | Defined in |
|---|---|---|---|
cluster | number | Index of the content cluster this source belongs to. | src/tools/research.ts:42 |
duplicates | number | How many other opened sources share this cluster. | src/tools/research.ts:46 |
primary | boolean | Whether this source is the representative of its cluster. | src/tools/research.ts:44 |
Variables#
researchInputSchema#
constresearchInputSchema: {count_per_query:ZodDefault<ZodNumber>;depth:ZodDefault<ZodEnum<["quick","deep"]>>;question:ZodString;recency_days:ZodOptional<ZodNumber>; }
Defined in: src/tools/research.ts:31
Input schema for web_research.
Type Declaration#
| Name | Type | Defined in |
|---|---|---|
count_per_query | ZodDefault<ZodNumber> | src/tools/research.ts:35 |
depth | ZodDefault<ZodEnum<["quick", "deep"]>> | src/tools/research.ts:33 |
question | ZodString | src/tools/research.ts:32 |
recency_days | ZodOptional<ZodNumber> | src/tools/research.ts:34 |
Functions#
collectCitations()#
collectCitations(
pages,sources,question,limit?,independence?):Citation[]
Defined in: src/tools/research.ts:217
Pick the spans of the opened pages that actually address the question.
The previous implementation took the first 400 characters of each page and never looked at the question, so the “answer” was usually page intros and boilerplate. Passages are now scored against the question with BM25 and the best ones returned with their offsets, which raises the signal and cuts the token count, since only matching paragraphs are included.
Parameters#
| Parameter | Type | Default value |
|---|---|---|
pages | readonly RoutedPage[] | undefined |
sources | readonly SearchSource[] | undefined |
question | string | undefined |
limit | number | MAX_EXCERPTS |
independence | readonly IndependenceResult[] | [] |
Returns#
Citation[]
queryTermCoverage()#
queryTermCoverage(
question,citations):number
Defined in: src/tools/research.ts:312
Fraction of the question’s content words that appear in the cited passages.
A blunt but honest measure of whether the citations engage with the question at all. It says nothing about correctness, which is not something this server can determine.
Parameters#
| Parameter | Type |
|---|---|
question | string |
citations | readonly Citation[] |
Returns#
number
registerResearch()#
registerResearch(
server,cache?):void
Defined in: src/tools/research.ts:450
Register the web_research tool (alias deep_search) on the given MCP server.
Parameters#
| Parameter | Type |
|---|---|
server | McpServer |
cache? | Cache |
Returns#
void
runResearch()#
runResearch(
args):Promise<ResearchResponse>
Defined in: src/tools/research.ts:354
Run a deep research query and return the spec-shaped response.
Exported separately so tests and the smoke harness can call the handler logic directly.
Parameters#
| Parameter | Type |
|---|---|
args | { cache?: Cache; count_per_query?: number; depth?: "deep" | "quick"; question: string; recency_days?: number; } |
args.cache? | Cache |
args.count_per_query? | number |
args.depth? | "deep" | "quick" |
args.question | string |
args.recency_days? | number |
Returns#
Promise<ResearchResponse>