Building a Custom MCP Server to Connect AI Assistants to Real Tools
Most businesses think of AI assistants as chatbots that answer questions inside a text box. The more interesting question is what happens when you give that assistant real tools — the ability to check the weather, search for hotels, send an email, or talk to a website directly. That is exactly what this project set out to build: a custom MCP (Model Context Protocol) server that turns a general-purpose AI assistant into an agent that can actually take action.
The Challenge
Large language models are excellent at reasoning and writing, but on their own they cannot check live data or perform real-world actions. Anthropic’s Model Context Protocol (MCP) solves this by giving an AI assistant a standard way to call external tools, but someone still has to build those tools, wire them together safely, and make them discoverable to the assistant.
The goal for this build was to create a lightweight, well-structured MCP server that could:
- Expose multiple independent tools (utility functions, live weather, hotel search, email delivery) through a single, consistent interface
- Run locally over stdio for development, and also be reachable remotely over SSE (Server-Sent Events) so it could be used from anywhere
- Be added straight into an AI assistant’s configuration alongside other MCP servers, with zero custom glue code on the client side
The Solution: A Custom MCP Server
We built the server using FastMCP, the official Python framework for creating MCP-compliant servers. FastMCP handles the protocol plumbing — tool registration, schema generation, transport — so the actual work is just writing plain Python functions and decorating them.
Architecture at a Glance
Each capability lives in its own module and gets registered on the MCP server as a @mcp.tool(). This keeps the codebase easy to extend: adding a new capability is just a new function and a one-line decorator.
from mcp.server.fastmcp import FastMCP
from hotel import search_hotels
mcp = FastMCP("Using MCP-tool for learning MCP")
@mcp.tool()
def get_weather(city: str) -> str:
"""Get weather details for a city"""
from weather import fetch_weather
return fetch_weather(city)
@mcp.tool()
def search_hotels_tool(city: str) -> str:
"""Find top hotels in a given city."""
return search_hotels(f"best hotels in {city}")
if __name__ == "__main__":
mcp.run(transport="stdio")Tools & Capabilities Built
Utility Tools
Simple tools to validate the protocol end-to-end during development — an add(a, b) calculator and a letter_counter(word, letter) tool — proving that the assistant could correctly call functions, pass arguments, and receive typed results.
Live Weather Lookup
Using LangChain’s OpenWeatherMapAPIWrapper (via the pyowm library), the assistant can ask for current conditions in any city and get a real, live answer back — not a guess from training data.
Hotel Search
A search_hotels tool queries Google Search results through SerpAPI and returns a clean, simplified list of titles, links, sources, and snippets — turning a messy search API response into something an assistant can reason over directly.
Email Automation
An SMTP-based send_email tool lets the assistant compose and send real emails on request — subject, body, and recipient all supplied by the assistant based on the conversation.
Multi-Server Orchestration
One of the more valuable parts of this project was proving that MCP servers can be mixed and matched. The assistant’s configuration registered three servers side by side:
- A local server running directly from a Python virtual environment via stdio
- A remote server hosted on Hugging Face Spaces, connected over SSE through
mcp-remote - A second local server for a separate, independent tool set
This shows the real power of MCP: capabilities don’t have to live in one monolithic codebase or even on one machine. An assistant can draw on local tools and cloud-hosted tools in the same conversation, with the client simply pointing at each server’s address.
Tech Stack
- Python 3.12+, managed with uv for fast, reproducible virtual environments
- FastMCP (
mcp[cli]) for the MCP server itself - LangChain, langchain-community, and langchain-openai for the weather wrapper and LLM tooling
- SerpAPI (
google-search-results) for live hotel/search results - pyowm for OpenWeatherMap integration
- python-dotenv for environment-based configuration
- Python’s built-in
smtplibfor email delivery
Security & Best Practices
API keys for SerpAPI and OpenWeatherMap are loaded from a local .env file via python-dotenv rather than being hardcoded, and the project keeps a .gitignore in place so secrets never get committed to version control. This is the pattern we recommend for any agentic AI build: keep credentials out of source code entirely, rotate them regularly, and use app-specific passwords rather than account passwords wherever a service supports it.
Results & Takeaways
The finished server gives an AI assistant a working toolbox: it can answer questions with live weather data, find hotels, send emails, and be extended with new tools in minutes. More importantly, it demonstrates a pattern that scales — local and remote MCP servers running side by side, each contributing tools to the same assistant, with no custom integration code required on the client.
This is the same MCP foundation that powers our broader agentic AI work — connecting AI assistants directly to real tools, real data, and real websites, instead of leaving them stuck answering from memory.
Want an MCP Server Built for Your Business?
If you want your AI assistant to check live data, talk to your internal systems, or take real actions on your website, we can design and build a custom MCP server for your workflow — the same way we built this one.