Skip to main content
Glama
nethravathik409-ui

mcp-server-tools-assignment

Assignment 2: MCP Server with 5 Tools

This project implements a small Model Context Protocol (MCP) server with five tools and a client that calls them over stdio.

What this project does

The server exposes five tools, each of which makes one GET request to a public API and returns only the relevant fields.

Tool

Input

Public API

Returned data

weather

city

https://wttr.in/{city}?format=j1

city, temp_c, condition, humidity

country_info

name

https://restcountries.com/v3.1/name/{name}

name, capital, region, population, currencies, languages

exchange_rates

base

https://open.er-api.com/v6/latest/{base}

base currency + selected rates

public_holidays

year, country_code

https://date.nager.at/api/v3/PublicHolidays/{year}/{country_code}

list of holiday objects with date, localName, name

define_word

word

https://api.dictionaryapi.dev/api/v2/entries/en/{word}

word and one or more short definitions

The client starts the server as a subprocess, lists the available tools, and calls each tool with sample input.

Related MCP server: AI Assistant Hub MCP Server

Project structure

mcp-server-tools-assignment/
├── client/
│   └── client.py
├── server/
│   ├── http.py
│   ├── server.py
│   └── tools/
│       ├── country.py
│       ├── dictionary.py
│       ├── exchange.py
│       ├── holidays.py
│       └── weather.py
├── config.py
├── README.md
├── requirements.txt
└── .venv/

Setup

cd mcp-server-tools-assignment
python3 -m venv .venv
. .venv/bin/activate
python -m pip install -r requirements.txt

Run the server directly

cd mcp-server-tools-assignment
. .venv/bin/activate
python -m server.server

This starts the MCP server over stdio.

Run the client

cd mcp-server-tools-assignment
. .venv/bin/activate
python client/client.py

This launches the server, lists the available tools, and calls each tool with sample data.

Notes on behavior

  • The project uses the mcp Python package and communicates over stdio transport.

  • The server and client are separate Python programs.

  • Each tool function makes one GET request to a public API and returns only the relevant fields.

  • Error handling is included so that invalid input or API failures do not crash the server.

Section 7 test cases and output

The following are the actual validation calls and representative outputs from the working project.

1) Weather

{'city': 'Mumbai'}

Output:

CASE:weather
{'meta': None, 'content': [{'type': 'text', 'text': '{\n  "city": "Mumbai",\n  "temp_c": 28.0,\n  "condition": "Light rain shower",\n  "humidity": 78\n}', 'annotations': None, 'meta': None}], 'structuredContent': None, 'isError': False}

2) Country info

{'name': 'India'}

Output:

CASE:country_info
{'meta': None, 'content': [{'type': 'text', 'text': '{\n  "name": "India",\n  "capital": "New Delhi",\n  "region": "Asia",\n  "population": 1380004385,\n  "currencies": [\n    "INR"\n  ],\n  "languages": [\n    "Hindi",\n    "English"\n  ]\n}', 'annotations': None, 'meta': None}], 'structuredContent': None, 'isError': False}

3) Exchange rates

{'base': 'USD'}

Output:

CASE:exchange_rates
{'meta': None, 'content': [{'type': 'text', 'text': '{\n  "base": null,\n  "rates": {\n    "USD": 1,\n    "EUR": 0.862295,\n    "INR": 95.581563,\n    "GBP": 0.738249,\n    "JPY": 160.045067,\n    "AUD": 1.395915,\n    "CAD": 1.389176,\n    "SGD": 1.273831\n  }\n}', 'annotations': None, 'meta': None}], 'structuredContent': None, 'isError': False}

4) Public holidays

{'year': 2025, 'country_code': 'US'}

Output:

CASE:public_holidays
{'meta': None, 'content': [{'type': 'text', 'text': '{\n  "date": "2025-01-01",\n  "localName": "New Year\'s Day",\n  "name": "New Year\'s Day"\n}', ... ], 'structuredContent': None, 'isError': False}

The output contains multiple holiday records, which confirms the tool is returning a non-empty list.

5) Dictionary lookup

{'word': 'example'}

Output:

CASE:define_word
{'meta': None, 'content': [{'type': 'text', 'text': '{\n  "word": "example",\n  "definitions": [\n    {\n      "partOfSpeech": "noun",\n      "meaning": "A thing characteristic of its kind or illustrating a general rule."\n    },\n    {\n      "partOfSpeech": "verb",\n      "meaning": "To serve as a pattern or model for others."\n    }\n  ]\n}', 'annotations': None, 'meta': None}], 'structuredContent': None, 'isError': False}

6) Failure path test

{'word': 'asdfghjkl'}

Output:

CASE:define_word
{'meta': None, 'content': [{'type': 'text', 'text': '{\n  "word": "asdfghjkl",\n  "definitions": [],\n  "error": "not found"\n}', 'annotations': None, 'meta': None}], 'structuredContent': None, 'isError': False}

This confirms the tool does not crash on a nonsense word; it returns a clean not found response, while valid words return real definitions.

Requirements

mcp<2
requests>=2.31.0

Purpose of the assignment

This assignment demonstrates how an MCP server exposes tools, how a client discovers them, and how the client calls them over stdio. It is a beginner-friendly example of how external APIs can be wrapped as tools that an AI or application can call in a structured and repeatable way.

Related MCP Connectors

Related MCP Servers