Skip to content

Instantly share code, notes, and snippets.

@mimoo
Last active June 6, 2025 13:59
Show Gist options
  • Save mimoo/d1388f63d911b821427aae0bfe19936f to your computer and use it in GitHub Desktop.
Save mimoo/d1388f63d911b821427aae0bfe19936f to your computer and use it in GitHub Desktop.

Revisions

  1. mimoo revised this gist Jun 6, 2025. 2 changed files with 24 additions and 17 deletions.
    9 changes: 4 additions & 5 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -2,8 +2,7 @@

    You need [uv](https://docs.astral.sh/uv/#installation), then:

    1. add websearch.py to some folder `FOLDER`
    2. add the file `.vscode/mcp.json` if it doesn't exist, with your new websearch MCP server (and edit the `FOLDER` part)
    3. voila


    1. add `websearch.py` to some folder `FOLDER`
    2. add the file `.vscode/mcp.json` if it doesn't exist, with your new websearch MCP server (and edit the `FOLDER` part). You can also do this by fuzzy searching for "MCP: Add Server" and adding the command `uv --directory FOLDER run python websearch.py --stdio` in the prompt.
    3. in the `mcp.json` you might want to put the full path to you `uv` instead of just `uv`. (do `which uv` in your terminal to get that full path)
    4. voila
    32 changes: 20 additions & 12 deletions websearch.py
    Original file line number Diff line number Diff line change
    @@ -1,27 +1,35 @@
    from __future__ import annotations

    from fastmcp import FastMCP
    from pydantic import BaseModel, Field
    from typing import List
    from duckduckgo_search import DDGS
    from pydantic import BaseModel
    from agents import Agent, Runner, WebSearchTool

    mcp_web = FastMCP(
    "secure-websearch-server",
    "openai-websearch-server",
    version="0.1.0",
    )

    websearch_agent = Agent(
    name="Websearch Agent",
    instructions="Search the web and provide a summary (with references) of the results based on the user's query.",
    tools=[WebSearchTool()],
    model="gpt-4.1-mini", # important: 4.1-mini is 10x cheaper than 4.1
    )


    class WebSearchArgs(BaseModel):
    query: str
    max_results: int = Field(default=5, ge=1, le=50)


    @mcp_web.tool()
    def search_web(args: WebSearchArgs) -> List[dict]:
    """
    Perform a web search using DuckDuckGo.
    Returns a list of search result dictionaries with 'title', 'href', and 'body'.
    """
    with DDGS() as ddgs:
    return ddgs.text(keywords=args.query, max_results=args.max_results)
    async def search_web(args: WebSearchArgs) -> str:
    """Perform a web search using the query, and summarize the results."""
    result = await Runner.run(
    websearch_agent,
    args.query,
    )
    return result.final_output


    if __name__ == "__main__":
    import argparse
  2. mimoo revised this gist May 26, 2025. 2 changed files with 7 additions and 3 deletions.
    6 changes: 5 additions & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,9 @@
    # Give vscode agent mode the power to do web searches

    You need [uv](https://docs.astral.sh/uv/#installation), then:

    1. add websearch.py to some folder `FOLDER`
    2. add the file `.vscode/mcp.json` if it doesn't exist, with your new websearch MCP server (and edit the `FOLDER` part)
    3. voila
    3. voila


    4 changes: 2 additions & 2 deletions mcp.json
    Original file line number Diff line number Diff line change
    @@ -7,8 +7,8 @@
    "--directory",
    "FOLDER",
    "run",
    "-m",
    "snarksentinel.llms.mcp.web_search",
    "python",
    "websearch.py",
    "--stdio"
    ]
    }
  3. mimoo created this gist May 26, 2025.
    5 changes: 5 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,5 @@
    # Give vscode agent mode the power to do web searches

    1. add websearch.py to some folder `FOLDER`
    2. add the file `.vscode/mcp.json` if it doesn't exist, with your new websearch MCP server (and edit the `FOLDER` part)
    3. voila
    16 changes: 16 additions & 0 deletions mcp.json
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,16 @@
    {
    "servers": {
    "websearch-mcp": {
    "type": "stdio",
    "command": "uv",
    "args": [
    "--directory",
    "FOLDER",
    "run",
    "-m",
    "snarksentinel.llms.mcp.web_search",
    "--stdio"
    ]
    }
    }
    }
    11 changes: 11 additions & 0 deletions pyproject.toml
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,11 @@
    [project]
    name = "websearch-mcp-server"
    version = "0.1.0"
    description = "search the web!"
    requires-python = ">=3.12"
    dependencies = [
    "duckduckgo-search>=8.0.2",
    "faiss-cpu>=1.10.0",
    "fastmcp>=2.2.6",
    ]

    38 changes: 38 additions & 0 deletions websearch.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,38 @@
    from __future__ import annotations

    from fastmcp import FastMCP
    from pydantic import BaseModel, Field
    from typing import List
    from duckduckgo_search import DDGS

    mcp_web = FastMCP(
    "secure-websearch-server",
    version="0.1.0",
    )

    class WebSearchArgs(BaseModel):
    query: str
    max_results: int = Field(default=5, ge=1, le=50)

    @mcp_web.tool()
    def search_web(args: WebSearchArgs) -> List[dict]:
    """
    Perform a web search using DuckDuckGo.
    Returns a list of search result dictionaries with 'title', 'href', and 'body'.
    """
    with DDGS() as ddgs:
    return ddgs.text(keywords=args.query, max_results=args.max_results)

    if __name__ == "__main__":
    import argparse
    import uvicorn

    parser = argparse.ArgumentParser()
    parser.add_argument("--stdio", action="store_true", help="Run on STDIO")
    parser.add_argument("--port", type=int, default=8003, help="Port for SSE")
    opts = parser.parse_args()

    if opts.stdio:
    mcp_web.run(transport="stdio")
    else:
    uvicorn.run(mcp_web.sse_app(), host="127.0.0.1", port=opts.port)