--- title: "Your first MCP server" description: "Get started with MCP by building a weather app in 5 minutes" --- Connect AI to anything. MCP (Model Context Protocol) lets your AI applications seamlessly interact with data sources, tools, and services. **Real-world example:** In this quickstart, we'll build an AI-powered weather app that lets users ask about current conditions in any city. Our app will use MCP to connect to a weather API. ![Weather App Demo](weather-app-demo.gif) ## Installation ```bash pip install mcp-sdk # Using pip uv add mcp-sdk # Using uv (recommended) ``` **Requirements:** - Python 3.8 or higher - pip or uv package manager ```bash npm install @modelcontextprotocol/sdk ``` **Requirements:** - Node.js 16 or higher - TypeScript 4.7 or higher - npm or yarn package manager ## Step 1: Create an MCP Server Our server will expose a tool that the AI can use to fetch the current weather for any city. ```python weather_server.py from mcp.server import Server from mcp.server.stdio import stdio_server import aiohttp server = Server("weather-server") @server.list_tools() async def list_tools(): return [{ "name": "get_weather", "description": "Get current weather for a city", "inputSchema": { "type": "object", "properties": { "city": {"type": "string"} } } }] @server.call_tool() async def call_tool(name: str, args: dict): if name == "get_weather": async with aiohttp.ClientSession() as session: city = args["city"] url = f"https://api.openweathermap.org/data/2.5/weather?q={city}&appid=YOUR_API_KEY" async with session.get(url) as resp: data = await resp.json() return data["weather"][0]["description"] async def main(): async with stdio_server() as (read, write): await server.run(read, write) if __name__ == "__main__": import asyncio asyncio.run(main()) ``` To make real API requests, sign up for a free API key at [OpenWeatherMap](https://openweathermap.org). ```typescript weather_server.ts import { Server } from "@modelcontextprotocol/sdk/server"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio"; import axios from "axios"; const server = new Server({ name: "weather-server", version: "1.0.0", }); server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [{ name: "get_weather", description: "Get current weather for a city", inputSchema: { type: "object", properties: { city: { type: "string" } } } }] }; }); server.setRequestHandler(CallToolRequestSchema, async (request) => { if (request.params.name === "get_weather") { const city = request.params.arguments?.city as string; const url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=YOUR_API_KEY`; const resp = await axios.get(url); return { toolResult: resp.data.weather[0].description }; } throw new Error("Tool not found"); }); async function main() { const transport = new StdioServerTransport(); await server.connect(transport); } main().catch(console.error); ``` To make real API requests, sign up for a free API key at [OpenWeatherMap](https://openweathermap.org). ## Step 2: Integrate the Server into Your AI App This example uses a mock AI model. In a real app, you would replace this with your actual AI model code that generates a response based on the user's message and any MCP context. ```python app.py from mcp.client import ClientSession from mcp.client.stdio import stdio_client import re def extract_city(message): match = re.search(r"in\s+(\w+)", message) if match: return match.group(1) else: return None async def get_weather(city): async with stdio_client(command="python weather_server.py") as (read, write): async with ClientSession(read, write) as session: await session.initialize() return await session.call_tool("get_weather", {"city": city}) async def handle_message(message): city = extract_city(message) if city: weather = await get_weather(city) return f"The current weather in {city} is: {weather}" else: return generate_response(message) # Your existing AI logic async def main(): while True: message = input("> ") response = await handle_message(message) print(response) if __name__ == "__main__": import asyncio asyncio.run(main()) ``` ```typescript app.ts import { Client } from "@modelcontextprotocol/sdk/client"; import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio"; import { CallToolResultSchema } from "@modelcontextprotocol/sdk/types"; import readline from "readline"; function extractCity(message: string): string | null { const match = message.match(/in\s+(\w+)/); if (match) { return match[1]; } else { return null; } } async function getWeather(city: string): Promise { const transport = new StdioClientTransport({ command: "ts-node weather_server.ts", }); const client = new Client({ name: "weather-app", version: "1.0.0", }); await client.connect(transport); const result = await client.request( { method: "tools/call", params: { name: "get_weather", arguments: { city } } }, CallToolResultSchema ); return result.toolResult as string; } async function handleMessage(message: string): Promise { const city = extractCity(message); if (city) { const weather = await getWeather(city); return `The current weather in ${city} is: ${weather}`; } else { return generateResponse(message); // Your existing AI logic } } const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); rl.prompt(); rl.on("line", async (line) => { const response = await handleMessage(line); console.log(response); rl.prompt(); }); ``` ## Step 3: Run It! In one terminal, start the server: ```bash python weather_server.py ``` In another terminal, start the app: ```bash python app.py ``` In one terminal, start the server: ```bash ts-node weather_server.ts ``` In another terminal, start the app: ```bash ts-node app.ts ``` Now chat with your AI assistant! Try asking about the weather in various cities. ``` > What's the weather like in Tokyo? The current weather in Tokyo is: few clouds > How about London? The current weather in London is: scattered clouds ``` ## Why MCP Rocks - **Effortless integrations.** No custom code needed to connect AI to any API, database, or service. - **Async built-in.** MCP client/server communication is fully asynchronous out of the box. - **Type-safe.** Requests and responses are validated against strict schemas. ## Next Steps Understand resources, tools, prompts and more Databases, APIs, embeddings, vectorstores... Expose your AI through an API or website Ensure your app is rock solid ## Getting Help Get support and see what others are building Look up library classes and functions Quick answers to common questions Report bugs or suggest improvements