ddg-text-search
Search the web for text-based information using DuckDuckGo's search engine with customizable filters for region, safe search, time limits, and result quantity.
Instructions
Search the web for text results using DuckDuckGo
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| keywords | Yes | Search query keywords | |
| region | No | Region code (e.g., wt-wt, us-en, uk-en) | wt-wt |
| safesearch | No | Safe search level | moderate |
| timelimit | No | Time limit (d=day, w=week, m=month, y=year) | |
| max_results | No | Maximum number of results to return |
Implementation Reference
- src/ddg_mcp/server.py:175-220 (handler)The handle_call_tool function dispatches to the specific handler for 'ddg-text-search'. It extracts parameters, performs the DuckDuckGo text search using DDGS().text(), formats the results into a numbered list with title, URL, and body, and returns as TextContent.@server.call_tool() async def handle_call_tool( name: str, arguments: dict | None ) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]: """ Handle tool execution requests. """ if not arguments: raise ValueError("Missing arguments") if name == "ddg-text-search": keywords = arguments.get("keywords") if not keywords: raise ValueError("Missing keywords") region = arguments.get("region", "wt-wt") safesearch = arguments.get("safesearch", "moderate") timelimit = arguments.get("timelimit") max_results = arguments.get("max_results", 10) # Perform search ddgs = DDGS() results = ddgs.text( keywords=keywords, region=region, safesearch=safesearch, timelimit=timelimit, max_results=max_results ) # Format results formatted_results = f"Search results for '{keywords}':\n\n" for i, result in enumerate(results, 1): formatted_results += ( f"{i}. {result.get('title', 'No title')}\n" f" URL: {result.get('href', 'No URL')}\n" f" {result.get('body', 'No description')}\n\n" ) return [ types.TextContent( type="text", text=formatted_results, ) ]
- src/ddg_mcp/server.py:93-107 (schema)The input schema and registration for the 'ddg-text-search' tool in the list_tools handler, defining parameters like keywords (required), region, safesearch, timelimit, and max_results.types.Tool( name="ddg-text-search", description="Search the web for text results using DuckDuckGo", inputSchema={ "type": "object", "properties": { "keywords": {"type": "string", "description": "Search query keywords"}, "region": {"type": "string", "description": "Region code (e.g., wt-wt, us-en, uk-en)", "default": "wt-wt"}, "safesearch": {"type": "string", "enum": ["on", "moderate", "off"], "description": "Safe search level", "default": "moderate"}, "timelimit": {"type": "string", "enum": ["d", "w", "m", "y"], "description": "Time limit (d=day, w=week, m=month, y=year)"}, "max_results": {"type": "integer", "description": "Maximum number of results to return", "default": 10}, }, "required": ["keywords"], }, ),
- src/ddg_mcp/server.py:86-173 (registration)The handle_list_tools function registers the 'ddg-text-search' tool among others by returning a list of Tool objects.@server.list_tools() async def handle_list_tools() -> list[types.Tool]: """ List available tools. Each tool specifies its arguments using JSON Schema validation. """ return [ types.Tool( name="ddg-text-search", description="Search the web for text results using DuckDuckGo", inputSchema={ "type": "object", "properties": { "keywords": {"type": "string", "description": "Search query keywords"}, "region": {"type": "string", "description": "Region code (e.g., wt-wt, us-en, uk-en)", "default": "wt-wt"}, "safesearch": {"type": "string", "enum": ["on", "moderate", "off"], "description": "Safe search level", "default": "moderate"}, "timelimit": {"type": "string", "enum": ["d", "w", "m", "y"], "description": "Time limit (d=day, w=week, m=month, y=year)"}, "max_results": {"type": "integer", "description": "Maximum number of results to return", "default": 10}, }, "required": ["keywords"], }, ), types.Tool( name="ddg-image-search", description="Search the web for images using DuckDuckGo", inputSchema={ "type": "object", "properties": { "keywords": {"type": "string", "description": "Search query keywords"}, "region": {"type": "string", "description": "Region code (e.g., wt-wt, us-en, uk-en)", "default": "wt-wt"}, "safesearch": {"type": "string", "enum": ["on", "moderate", "off"], "description": "Safe search level", "default": "moderate"}, "timelimit": {"type": "string", "enum": ["d", "w", "m", "y"], "description": "Time limit (d=day, w=week, m=month, y=year)"}, "size": {"type": "string", "enum": ["Small", "Medium", "Large", "Wallpaper"], "description": "Image size"}, "color": {"type": "string", "enum": ["color", "Monochrome", "Red", "Orange", "Yellow", "Green", "Blue", "Purple", "Pink", "Brown", "Black", "Gray", "Teal", "White"], "description": "Image color"}, "type_image": {"type": "string", "enum": ["photo", "clipart", "gif", "transparent", "line"], "description": "Image type"}, "layout": {"type": "string", "enum": ["Square", "Tall", "Wide"], "description": "Image layout"}, "license_image": {"type": "string", "enum": ["any", "Public", "Share", "ShareCommercially", "Modify", "ModifyCommercially"], "description": "Image license type"}, "max_results": {"type": "integer", "description": "Maximum number of results to return", "default": 10}, }, "required": ["keywords"], }, ), types.Tool( name="ddg-news-search", description="Search for news articles using DuckDuckGo", inputSchema={ "type": "object", "properties": { "keywords": {"type": "string", "description": "Search query keywords"}, "region": {"type": "string", "description": "Region code (e.g., wt-wt, us-en, uk-en)", "default": "wt-wt"}, "safesearch": {"type": "string", "enum": ["on", "moderate", "off"], "description": "Safe search level", "default": "moderate"}, "timelimit": {"type": "string", "enum": ["d", "w", "m"], "description": "Time limit (d=day, w=week, m=month)"}, "max_results": {"type": "integer", "description": "Maximum number of results to return", "default": 10}, }, "required": ["keywords"], }, ), types.Tool( name="ddg-video-search", description="Search for videos using DuckDuckGo", inputSchema={ "type": "object", "properties": { "keywords": {"type": "string", "description": "Search query keywords"}, "region": {"type": "string", "description": "Region code (e.g., wt-wt, us-en, uk-en)", "default": "wt-wt"}, "safesearch": {"type": "string", "enum": ["on", "moderate", "off"], "description": "Safe search level", "default": "moderate"}, "timelimit": {"type": "string", "enum": ["d", "w", "m"], "description": "Time limit (d=day, w=week, m=month)"}, "resolution": {"type": "string", "enum": ["high", "standard"], "description": "Video resolution"}, "duration": {"type": "string", "enum": ["short", "medium", "long"], "description": "Video duration"}, "license_videos": {"type": "string", "enum": ["creativeCommon", "youtube"], "description": "Video license type"}, "max_results": {"type": "integer", "description": "Maximum number of results to return", "default": 10}, }, "required": ["keywords"], }, ), types.Tool( name="ddg-ai-chat", description="Chat with DuckDuckGo AI", inputSchema={ "type": "object", "properties": { "keywords": {"type": "string", "description": "Message or question to send to the AI"}, "model": {"type": "string", "enum": ["gpt-4o-mini", "llama-3.3-70b", "claude-3-haiku", "o3-mini", "mistral-small-3"], "description": "AI model to use", "default": "gpt-4o-mini"}, }, "required": ["keywords"], }, ), ]