How to build an AI agent and MCP server step by step
Most AI agents can plan, write, and chat—but they often don’t know what’s happening in the real world. That’s where MCP (Model Context Protocol) comes in. By connecting your agent to an MCP server, you can let it call external tools like Google Trends, databases, or code runners, all in a clean and scalable way.
What is MCP and why does it matter?
MCP stands for Model Context Protocol. Despite the technical-sounding name, the idea is simple: it’s a standard way for AI agents to talk to external tools.
You can think of MCP as a translator sitting between two sides:
On one side, you have your AI agent powered by a language model. On the other side, you have tools that do specific jobs—like fetching Google Trends data, querying a database, or running custom Python code. The agent can’t directly run those tools, so MCP defines how they communicate.
The tools run as separate programs (usually in their own processes). The agent connects to them over standard input and output (stdin/stdout), asks what tools are available, and then calls them with arguments. Results are sent back as JSON.
How MCP works under the hood
The basic loop of MCP is surprisingly straightforward:
First, the tool runs as its own small program. It doesn’t share memory or environment with the agent. Instead, the agent connects to it over stdin/stdout.
When the connection is established, the agent asks the MCP server: “What tools do you have?” The MCP server responds with a list of tools, including their names, arguments, and what they return. This description is provided as schemas, so the agent can understand how to call each tool.
Once the agent knows what’s available, it can say: “Call this tool with these arguments.” The MCP server runs the underlying function, captures the result, and returns it as JSON. From the agent’s perspective, it’s just making a structured call and getting structured data back.
The key idea is separation: the agent doesn’t need to know how the tool is implemented, what libraries it uses, or even which programming language it’s written in. As long as the tool speaks MCP, the agent can use it.
Why MCP is powerful for AI agents
MCP brings several important benefits when you’re building agents:
1. Isolation. Each tool runs in its own process. If a tool crashes or misbehaves, your agent doesn’t go down with it. You can restart or replace the tool without touching the agent logic.
2. Interoperability. You can write tools in Python, Go, Node, or any language you like. The agent doesn’t care—it just talks MCP. This makes it easier to reuse existing codebases and services.
3. Discoverability. Tools describe themselves with schemas: names, parameters, types, and descriptions. The agent can discover at runtime what tools exist and how to call them, without hardcoding every detail.
4. Scalability. You can add new tools, version old ones, or swap implementations without rewriting your agent. The agent simply sees a list of tools and their schemas and uses them accordingly.
If you think of the agent as the brain, MCP is the wire that connects it to its hands and eyes. The brain decides what to do, MCP carries the request, and the tools act on the real world. The results flow back to the brain, making the agent more than just a static chatbot.
Starting point: a simple blog-writing agent
Imagine you already have an AI agent that writes blog posts. You give it a topic, and it plans the sections, writes a draft, and suggests alternative titles. This is similar to many modern AI content workflows and to guides like setting up your first AI agent.
That agent is useful, but it’s limited: it only relies on the language model. It doesn’t know what’s trending today, what’s in the news, or what people are actually searching for right now.
To fix that, you can connect it to an MCP server that exposes a Google Trends tool. Then, before writing, the agent can fetch live trending queries and ground its content in real data.
Designing an MCP server for Google Trends
The goal is to build a small Python program that acts as an MCP server and exposes a single tool called trends. Your agent will call this tool whenever it needs to see what’s trending on Google Trends.
You can think of this server like a tiny web service, but instead of using HTTP, it communicates over stdin/stdout using the Model Context Protocol. The agent launches it as a separate process and talks to it through the MCP handshake and message format.
Wrapping a Python function as an MCP tool
The core of the server is a plain Python function, for example trends(), that takes JSON-friendly arguments and returns a JSON-friendly dictionary. This function might accept parameters like region, category, or time range, then call the Google Trends API or a wrapper library, and finally return the trending queries.
To make this function usable over MCP, you wrap it as an SDK tool. A helper like function_tool() inspects the function’s signature and docstring, and automatically builds a schema for it. This schema includes:
• The tool’s name
• The parameters and their types
• A description of what the tool does
• The structure of the returned data
Because of this, you don’t need to manually write JSON schemas. From this point on, the agent development kit (ADK) knows what arguments the tool expects and what it returns, which makes the tool discoverable and safe to call.
Creating the MCP server object
Next, you create an MCP server object. This object represents the small program that sits between the agent and your trends tool. It speaks MCP over stdin/stdout and handles the protocol details.
The server is usually initialized with a name—an identifier the client (your agent) will see during the handshake. Alongside that, you define handlers for the two key operations:
1. Listing tools. When the agent connects, it asks the server what tools are available. Your server responds with a list containing the trends tool, converted into an MCP tool schema. A helper such as adk_to_mcp_tool_type() can take the metadata from your wrapped function and transform it into exactly what the MCP client expects.
2. Calling a tool. When the agent wants to use trends, it sends the tool name plus a JSON dictionary of arguments. The server checks that the name matches an available tool, then forwards the arguments into your Python function by calling the async wrapper around the tool. Whatever the function returns is JSON-dumped and sent back as a text content payload.
If anything goes wrong, the server can return a small JSON error object and log the details to standard error. The important thing is that the protocol stays simple: name + arguments in, JSON results out.
Attaching the server to stdin/stdout
Once the MCP server object is defined, you need to attach it to stdin and stdout and start the handshake. A helper function opens the transport, wires up the read and write streams, and passes them into the MCP server.
During initialization, you can also send metadata and capability information that the client will see. Then, in the main block of your script, you call something like asyncio.run() to start the server process and keep it running while the agent interacts with it.
From that moment on, your ADK-based agent can launch the script, ask for the list of tools, and call trends just like any other tool.
Connecting the MCP server to your agent
With the MCP server in place, the final step is to wire it into your main agent configuration. In your main agent.py file, you add the trends MCP server to the root agent’s list of tools, right next to existing tools like the planner and writer.
From the agent’s perspective, there’s no functional difference between calling a local function tool and calling the MCP-based trends tool. The agent simply sees a tool with a schema, passes arguments, and gets back JSON.
The big difference is in behavior: instead of guessing what’s trending, the agent can now fetch real, live Google Trends data before it starts writing a blog post. That means more relevant titles, sections, and examples aligned with what people are actually searching for.
This pattern is similar to how more advanced agents are built in other domains, such as the way an AI arbitrage bot might call price feeds and exchanges, as shown in guides like building an AI-powered crypto arbitrage agent.
Testing your MCP-powered agent
Once everything is wired up, you can start your agent’s web UI (for example, via an ADK command) and interact with it as usual. Under the hood, when you ask it to write a blog post on a topic, the agent can decide to call the trends tool first, pull in trending queries, and then use that context to plan and write.
Because MCP keeps tools isolated and discoverable, you can continue to expand this setup: add more tools, version them, or replace implementations without rewriting your agent logic.
Key takeaways
By connecting your AI agent to an MCP server, you turn a static, model-only chatbot into a dynamic agent that can reach into the real world. MCP gives you:
• A clean protocol for agents to call external tools
• Isolation between the agent and tools
• Language-agnostic, interoperable integrations
• Discoverable, schema-based tool definitions
• A scalable way to add and manage capabilities over time
Starting from a simple blog-writing agent and adding a Google Trends MCP server is a great first step. From there, you can keep extending your agent with more tools and even move toward multi-agent systems that collaborate using the same pattern.
Comments
No comments yet. Be the first to share your thoughts!