Agent AI And MCP (Model Context Protocol)
Building My First AI Agent Using MCP and Gemini – Understanding the Complete Flow
When I first started learning AI Agents and the Model Context Protocol (MCP), I found plenty of tutorials that showed how to write the code, but very few explained why each piece exists and how everything works together.
This article explains a simple AI Agent built using:
Node.js
Google Gemini
Model Context Protocol (MCP)
By the end, you'll understand:
What an AI Agent actually is
How MCP fits into the architecture
Why the LLM doesn't need to see tool implementations
How tool selection really works
What We Are Building
Our project contains only two files.
app.js
server.js
Although the project is small, it demonstrates the same basic architecture used by many production AI agents.
The flow looks like this:
User
│
▼
app.js
│
┌───────────┴────────────┐
▼ ▼
Gemini LLM MCP Client
│
STDIO Transport
│
▼
MCP Server
│
▼
getCurrentTime Tool
Notice something important:
Gemini never directly calls the tool.
The application (app.js) coordinates everything.
Our AI Agent project depends on four npm packages. Install them using the following command:
npm install @google/genai @modelcontextprotocol/sdk dotenv zodThis command installs all the required packages and automatically updates the package.json file.
Understanding app.js
The responsibility of app.js is not to calculate the current time.
Its responsibility is to act as the AI Agent.
It performs six jobs:
Connect to Gemini.
Connect to the MCP server.
Discover available tools.
Ask Gemini which tool should be used.
Execute the selected tool.
Ask Gemini to generate the final response.
Let's understand each step.
Step 1 – Connect to Gemini
const ai = new GoogleGenAI({
apiKey: process.env.GEMINI_API_KEY
});
This creates a client capable of communicating with Gemini.
At this point no AI request has been made.
Step 2 – Start the MCP Server
const transport = new StdioClientTransport({
command: "node",
args: ["server.js"]
});
This starts:
node server.js
behind the scenes.
Now the MCP server is running.
Step 3 – Connect the MCP Client
await client.connect(transport);
The client and server are now connected through STDIO.
Think of it as opening a communication channel.
Step 4 – Discover Available Tools
const { tools } = await client.listTools();
This is one of the most important lines in the application.
The agent asks the MCP server:
"Tell me which tools you provide."
The server responds with something similar to:
[
{
"name": "getCurrentTime",
"title": "Current Time",
"description": "Returns the current system time.",
"inputSchema": {}
}
]
Notice that Gemini has not been involved yet.
This communication happens only between the MCP client and MCP server.
Step 5 – Ask Gemini Which Tool to Use
Suppose the user asks:
What is the current time?
Our application creates this prompt:
You are an AI Agent.
User Question:
What is the current time?
Available Tools:
getCurrentTime
Reply ONLY with the tool name.
Gemini responds with:
getCurrentTime
At this point Gemini has only selected the tool.
It has not executed anything.
Step 6 – Execute the Tool
The application now calls:
await client.callTool({
name: selectedTool,
arguments: {}
});
The MCP server receives the request and executes the tool.
For our example, the tool returns:
10:45:31 PM
Step 7 – Generate the Final Response
Now the application asks Gemini one more time.
User Question:
What is the current time?
Tool Result:
10:45:31 PM
Write a nice response.
Gemini finally replies:
The current time is 10:45:31 PM.
The user never sees the intermediate steps.
Understanding server.js
The server has only one responsibility:
Provide tools.
It does not communicate with the user.
It does not ask Gemini anything.
It simply exposes capabilities.
Our server registers one tool:
server.registerTool(
"getCurrentTime",
{
title: "Current Time",
description: "Returns the current system time.",
inputSchema: {}
},
async () => {
const now = new Date().toLocaleTimeString();
return {
content: [
{
type: "text",
text: now
}
]
};
}
);
This contains two parts.
Metadata
{
title: "Current Time",
description: "Returns the current system time.",
inputSchema: {}
}
This describes what the tool does.
Implementation
async () => {
const now = new Date().toLocaleTimeString();
...
}
This contains the actual JavaScript code.
Does Gemini See the Implementation?
This was the biggest question I had while learning.
The answer is:
No.
Gemini never sees:
const now = new Date().toLocaleTimeString();
Instead, it only receives information similar to:
Tool Name:
getCurrentTime
Description:
Returns the current system time.
This is enough for Gemini to understand when the tool should be used.
The implementation always remains on the server.
Why Doesn't the LLM Need the Code?
Imagine you are given a C# method:
GetCurrentTime()
Even without reading the implementation, you can probably guess what it does.
Programmers intentionally choose descriptive names.
Large Language Models have been trained on millions of code examples and API definitions.
They learn these naming patterns.
When necessary, descriptions provide even more context.
The LLM reasons over the tool's contract, not its implementation.
Is This Really an AI Agent?
Yes.
The application performs the basic agent loop:
User
│
▼
Understand Request
│
▼
LLM Chooses Tool
│
▼
Execute Tool
│
▼
Observe Result
│
▼
LLM Generates Final Answer
This is the foundation of an AI Agent.
More advanced agents add memory, planning, multiple tools, retrieval, and autonomous reasoning, but the core loop remains the same.
Where Does MCP Fit?
One misconception is that MCP is the AI Agent.
It is not.
MCP is simply a communication protocol.
Just as HTTP allows browsers to communicate with web servers, MCP allows AI applications to communicate with tools.
The agent is the orchestration logic.
MCP is one way that the agent talks to external capabilities.
Source Code
The complete source code for this project is available on GitHub.
You can clone the repository, explore the implementation, and run the project locally while following this article. or https://github.com/PersonSimple/ai-mcp-tools.git
GitHub Repository: ai-mcp-tools
The repository includes:
app.js– Implements the AI Agent by interacting with the Gemini LLM and the MCP Server.server.js– Implements the MCP Server and exposes thegetCurrentTimetool.package.json– Contains the project configuration and required npm dependencies..env.example– Template for configuring your Gemini API key.Complete project structure required to run the application.
Feel free to clone the repository, experiment with the code, extend it with additional MCP tools, and use it as a starting point for building your own AI Agents.
Final Thoughts
Building this small project taught me that AI Agents are not magic.
They are applications that coordinate:
an LLM for reasoning,
tools for performing actions,
and protocols like MCP for communication.
Once I understood that separation, the overall architecture became much easier to understand.
This project may be simple, but it demonstrates the same ideas used by much larger AI systems.
If you're beginning your AI journey, my advice is simple:
Don't just copy the code.
Ask why every line exists.
That's where the real learning happens.
Comments
Post a Comment