Tutorial: Creating and Using a Brave Search MCP Server in Claude Desktop
Why MCP?
LLMs are typically siloed applications, with no access to external data or the ability to take actions on your behalf. Anthropic’s Model-Context Protocol (MCP) enables external “tools” or “servers” to be invoked by large language models (LLMs) such as Claude, bridging the gap between the AI and external data sources. This allows AI applications to not just pull from data sources to enrich the context with high quality content (read), but also take actions on the users behalf (write).
Overview
In this tutorial, you will build a complete MCP server in Python that enables Claude to query the Brave Search API, and integrate it into Claude Desktop so you can perform web searches right from your local Claude desktop application. We will go step by step, providing full code and explanation. Finally, we will demonstrate testing our application with a sample query and showing off what it can do!
Prerequisites
Python 3.10 or higher
You can check your Python version by running:
Claude Desktop (latest version)
Ensure you have installed the latest version of Claude for Desktop on macOS or Windows.
Brave Search API key
You can obtain an API key from Brave (requires an account). Once you have your key, keep it at hand to insert into the environment variables in our configuration.
1. Project Setup
Create the project directory
Create and activate a Python virtual environment
Then activate it:
Unix/macOS:
Windows:
Install required packages
We will be using
httpx
for making asynchronous HTTP requests andmcp
(the Python MCP SDK) for quickly creating our MCP server:
2. Create the Server Code
Create a new file called brave.py
in the brave-search
directory. We will build it up bit by bit for clarity. Below is the complete listing, which you can copy in full if you prefer. However, let’s walk through the important parts step by step.
2.1 Imports and Initialisation
At the top of brave.py
, add:
FastMCP("brave-search")
: This name ("brave-search") must match the name you put in your Claude Desktop configuration.BRAVE_API_KEY
: Declared at the top, but we will fetch it from the environment later (to keep secrets secure).
2.2 Helper Function: make_brave_request
Next, define a helper function for contacting the Brave API. This wraps httpx.AsyncClient
calls and adds any required headers:
2.3 Formatting the Web Search Results
We will need a utility function to format the JSON results from Brave into a simple string for display:
2.4 Creating the Actual MCP Tool
We want to expose a single tool, brave_web_search
, so that Claude can call it with a query, count
, and offset
. That way, when you type a question into Claude, the model can decide to use this tool if it needs search data:
2.5 Putting It All Together: if __name__ == "__main__":
Finally, at the bottom of brave.py
, we set the global BRAVE_API_KEY
from the environment (so we never hard‑code it) and then start the server:
Your final brave.py
file should look like this (all the snippets above, in order). Once ready, save it.
3. Configure Claude Desktop
With our MCP server code in place, we next tell Claude Desktop how to launch it.
Open the Claude Desktop configuration file
The file location depends on your operating system:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.json
Windows:
%APPDATA%\\Claude\\claude_desktop_config.json
If you have VSCode you can open it the config file into your editor witht he following command:
code ~/Library/Application\\ Support/Claude/claude_desktop_config.json
Add the MCP server configuration
Insert or update the
mcpServers
section of your JSON. Below is an example:Important points:
"brave-search"
in the config must matchFastMCP("brave-search")
inbrave.py
.Use absolute paths for both the Python interpreter (within the virtual environment) and the
brave.py
script.The
u
flag ensures unbuffered output. This helps Claude Desktop properly capture the MCP server’s log output in real time.We provide
BRAVE_API_KEY
via theenv
object so it is not hard‑coded in the source.
Restart Claude Desktop
After saving your
claude_desktop_config.json
changes, fully quit and restart Claude Desktop. Upon relaunch, it should read your new configuration and attempt to start the “brave-search” MCP server automatically.
4. Testing the Brave Search MCP Server
Once Claude Desktop restarts, you can confirm if your server is recognised:
Look for the Hammer Icon
A hammer icon or “tools” icon should appear in the Claude Desktop interface once at least one MCP server is running successfully.
Inspect Tools
Clicking the hammer icon should show a list of tools provided by the servers. Here, you should see a tool named
brave_web_search
.
Try a Test Query
Go back to the main chat input in Claude Desktop and type something that might trigger the search. For example:
“What is the latest RL model by DeepSeek?”
Claude may attempt to call brave_web_search
with this query. You should see a message from Claude indicating it is “Making a tool request: brave_web_search”. If everything is working, it will present you with the Brave search results.
Viewing Detailed Logs
If you need to examine the server’s logs for debugging or if the server fails to start, you can do:
(on macOS). On Windows, logs typically reside under %UserProfile%\\AppData\\Roaming\\Claude\\Logs\\
. You may also go to Claude Desktop → Settings → Developer to open the logs folder. For failing MCP servers, a dedicated logs subfolder is generated, allowing you to see full tracebacks and debug messages.
5. Debugging and Troubleshooting
5.1 Common Issues
ModuleNotFoundError
Ensure your virtual environment is active when installing packages.
Verify by running
pip list | grep mcp
(Unix/macOS) orpip list | findstr fastmcp
(Windows).
Server Disconnection
Make sure all paths in
claude_desktop_config.json
are absolute.Verify the Python path is correct.
Check if
brave.py
exists where you specified.
BRAVE_API_KEY
not foundDouble check you placed the
BRAVE_API_KEY
in theenv
object of your config.Confirm the key is valid.
No Tools Visible
Has Claude Desktop properly restarted after adding your new config?
Check the hammer icon at the top of the chat interface.
5.2 Detailed Logs in Claude Desktop
You can inspect advanced logs and debug MCP servers by going to Settings → Developer within Claude Desktop. There, you will find full debug logs for each MCP server. If you see a log folder titled something like mcp_brave-search_2025-01-21_…
, that will contain the standard error and standard output logs.
5.3 Testing from Scratch
If you suspect the server is not even starting, you can launch brave.py
manually in a terminal:
If that runs fine and waits, then the server is OK on its own—so any issues must lie in the Desktop config or the environment variables.
6. Sample End‑to‑End Usage
To demonstrate a complete cycle:
Launch/Restart Claude Desktop
Wait until Claude logs that the “brave-search” server is successfully connected.
Enter Query
In Claude’s chat input, type (for example):
“What is the latest RL model by DeepSeek?”
Behind the Scenes
Claude analyses your prompt.
Decides it needs to use the “brave_web_search” tool.
Calls your MCP server, passing the query string.
The server calls the Brave API, receives a JSON payload, and formats the result.
The result is returned to Claude, which then writes its final answer.
View the Results
Claude will generate a response, aided by the websites it has visited with the help of the MCP tool.
If you want to see even more detail about what Claude is doing, you can enable developer tools in Claude Desktop and open logs or watch the console output. This level of inspection is particularly useful if you’re building advanced MCP servers or diagnosing subtle integration problems.
Conclusion
Congratulations! You have built a fully functional MCP server in Python that brings Brave Search capabilities into your Claude Desktop environment. You can now further customise your MCP server by adding new tools or integrating other external APIs (e.g. weather, local file access, or advanced search features).
At Valyu, we are excited by tools such as MCP because they align with our vision to make high quality content and knowledge both accessible and monetisable for AI.
We’re excited to release an updated Valyu Context Enrichment API, in the coming weeks, with a Native MCP integration following soon after - where you’ll be able to hook up Valyu data to existing supported chat model such as Claude.
Feel free to drop @yorkeccak a message on X if you have any questions.