text_web_search
Search the web by submitting a text query. Customize region, result count, and pages to fetch.
Instructions
Perform a text web search using the provided query using DDGS.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | The search query to fetch results for. It should be a non-empty string. | |
| region | No | Optional region to search in. | uk-en |
| max_results | No | The maximum number of results to return. Default is 10, maximum is 100. | |
| pages | No | The number of pages to fetch. Default is 1, maximum is 10. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- src/pymcp/server.py:181-219 (handler)The 'text_web_search' handler function that performs a text web search using DDGS (DuckDuckGo Search). It accepts query, region, max_results, and pages parameters, and returns a list of search result dictionaries.
async def text_web_search( self, ctx: Context, query: Annotated[ str, Field( ..., description="The search query to fetch results for. It should be a non-empty string.", ), ], region: Annotated[ str | None, Field(default="uk-en", description="Optional region to search in."), ] = "uk-en", max_results: Annotated[ int | None, Field( default=10, ge=1, le=100, description="The maximum number of results to return. Default is 10, maximum is 100.", ), ] = 10, pages: Annotated[ int | None, Field( default=1, ge=1, le=10, description="The number of pages to fetch. Default is 1, maximum is 10.", ), ] = 1, ) -> list[dict[str, Any]]: """Perform a text web search using the provided query using DDGS.""" await ctx.info(f"Performing text web search for query: {query}") results = DDGS().text(query=query, region=region, max_results=max_results, page=pages) if results: await ctx.info(f"Found {len(results)} results for the query.") return results - src/pymcp/server.py:181-213 (schema)The input schema for the text_web_search tool, defined via type annotations and Pydantic Field descriptors: 'query' (str, required), 'region' (str | None, default 'uk-en'), 'max_results' (int | None, default 10, ge=1, le=100), and 'pages' (int | None, default 1, ge=1, le=10).
async def text_web_search( self, ctx: Context, query: Annotated[ str, Field( ..., description="The search query to fetch results for. It should be a non-empty string.", ), ], region: Annotated[ str | None, Field(default="uk-en", description="Optional region to search in."), ] = "uk-en", max_results: Annotated[ int | None, Field( default=10, ge=1, le=100, description="The maximum number of results to return. Default is 10, maximum is 100.", ), ] = 10, pages: Annotated[ int | None, Field( default=1, ge=1, le=10, description="The number of pages to fetch. Default is 1, maximum is 10.", ), ] = 1, ) -> list[dict[str, Any]]: - src/pymcp/server.py:63-66 (registration)Tool registration metadata entry for 'text_web_search' in the PyMCP.tools list, with tags 'meta-search', 'text-search', and 'searchexample'. This entry is used by MCPMixin.register_features() to register the tool with FastMCP.
{ "fn": "text_web_search", "tags": ["meta-search", "text-search", "searchexample"], }, - src/pymcp/mixin.py:34-39 (registration)The register_features loop that iterates over self.tools, looks up the method by fn name (e.g., 'text_web_search') via getattr, and registers it as an MCP tool using mcp.tool().
for tool in self.tools: assert "fn" in tool, "Tool metadata must include the 'fn' key." tool_copy = copy.deepcopy(tool) fn_name = tool_copy.pop("fn") fn = getattr(self, fn_name) mcp.tool(**tool_copy)(fn) # pass remaining metadata as kwargs - src/pymcp/server.py:435-443 (helper)The tool 'text_web_search' is excluded from response caching because it produces non-deterministic results (line 436-438).
# Only deterministic tools are included in caching. # Tools like 'generate_password', 'text_web_search', 'pirate_summary', and 'vonmises_random' are excluded # because they produce non-deterministic or time-sensitive results, and caching their # outputs could lead to stale or incorrect responses. call_tool_settings=CallToolSettings( included_tools=["greet", "permutations"], ttl=EnvVars.RESPONSE_CACHE_TTL, enabled=EnvVars.RESPONSE_CACHE_TTL > 0, ),