MCP Servers in Python
by Rwanbt
README.md
# MCP Servers in Python
A local Programming Learning MCP Server built with FastMCP.
## Description
This project exposes a small catalog of programming study topics through the Model Context Protocol (MCP). A deterministic agent-like client searches the catalog, retrieves complete topic details through MCP, and formats a short recommendation for a student. The server and client remain separate: the client starts the server as a subprocess and communicates with it over the MCP `stdio` transport.
Project structure:
```text
mcp-intro/
├── server/
│ ├── learning_server.py
│ └── __init__.py
├── client/
│ ├── mcp_client.py
│ ├── agent.py
│ └── __init__.py
├── data/
│ └── topics.json
├── output/
│ └── sample_agent_response.md
├── README.md
├── requirements.txt
├── .env.example
└── .gitignore
```
## MCP Architecture Summary
MCP is a protocol that gives AI applications a standard way to discover and use external capabilities instead of requiring a custom integration for every service.
- An **MCP host** is the application managing the user interaction and the overall AI experience. A host can connect to several servers, normally through one client connection per server.
- An **MCP client** manages one protocol connection, discovers the server's capabilities, sends tool calls or resource requests, and returns the results to the host.
- An **MCP server** exposes a focused set of capabilities and handles requests for them. In this project, it reads only the local topic dataset.
- A **tool** is an executable function with a typed input schema. For example, the agent calls `search_topics` with a query.
- A **resource** is read-only context identified by a URI. For example, `topics://catalog` returns the available topic ids and titles.
- A **prompt** is a reusable message template exposed by a server. This project does not expose prompts because they are not needed for the study lookup flow.
A server should expose only necessary capabilities. A small capability surface reduces accidental actions, limits access to data and credentials, and makes the server easier to understand and audit. Here, every exposed capability is read-only and limited to `data/topics.json`.
## Requirements
- Python 3.10 or newer
- `fastmcp==3.4.4`
- `python-dotenv==1.1.1`
No API key, LLM account, database, or external service is required.
## Setup
```bash
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
```
The default server path is `server/learning_server.py`. To override it, create `.env` from `.env.example` and change `MCP_SERVER_PATH`. The `.env` file is ignored by Git.
## How to Run the Server
Start the server directly with the local `stdio` transport:
```bash
python server/learning_server.py
```
A `stdio` MCP server waits for protocol messages on standard input. In normal use, the client starts this process automatically, so a separate server terminal is not required.
## How to Test the Server
Run the validation client:
```bash
python -m client.mcp_client
```
This command starts the server through MCP and verifies that:
- the server starts and completes the MCP handshake;
- `search_topics` and `get_topic_details` are discoverable;
- a valid decorators search returns results;
- a valid topic id returns complete details;
- an unknown id returns a clear error object;
- an empty query returns the message `Search query must not be empty.`;
- an unrelated query returns no matches;
- `topics://catalog` is discoverable and readable.
The tested server exposes these capability names:
```text
Tools: search_topics, get_topic_details
Resource: topics://catalog
```
## How to Run the Agent
Run the suggested example:
```bash
python -m client.agent "I want to study Python decorators. What should I review first?"
```
The program calls `search_topics`, selects the best result, calls `get_topic_details`, prints the student-facing answer, and writes it to `output/sample_agent_response.md`.
Use another question or output path when needed:
```bash
python -m client.agent "How do Python generators work?" --output output/generators.md
```
The agent never imports the server functions. `client/mcp_client.py` creates a FastMCP client from the server script path, which launches the server as an external subprocess and communicates through MCP over `stdio`.
## Available Tools
### `search_topics`
- **Input:** `query: str`
- **Behavior:** performs deterministic, case-insensitive matching against topic ids, titles, summaries, and key concepts.
- **Output:** up to five ranked matches containing `id`, `title`, `summary`, and `key_concepts`.
- **No match:** returns an empty list.
- **Invalid input:** an empty query produces a clear MCP tool error.
- **Side effects:** none; the tool is marked read-only and closed-world.
### `get_topic_details`
- **Input:** `topic_id: str`
- **Behavior:** performs an exact, case-insensitive id lookup.
- **Output:** the full topic object, including prerequisites, key concepts, common mistakes, and a practice idea.
- **Unknown id:** returns an object containing a clear `error` message.
- **Side effects:** none; the tool is marked read-only and closed-world.
## Available Resources
### `topics://catalog`
A read-only `application/json` resource containing only the available topic ids and titles. It is intended for browsing and does not modify the dataset.
Example shape:
```json
[
{"id": "python-functions", "title": "Python Functions"},
{"id": "python-decorators", "title": "Python Decorators"}
]
```
## Third-Party MCP Server Review
The reviewed third-party server is the [official GitHub MCP Server](https://github.com/github/github-mcp-server). The review was based on its repository documentation; it was not installed and no credentials were provided.
- **Purpose:** connects MCP hosts to GitHub so an agent can inspect repositories and code, work with issues and pull requests, examine Actions, and access other GitHub features.
- **Location:** it can run remotely as a GitHub-hosted HTTP server or locally as a Docker container/native Go binary using `stdio`.
- **Capabilities:** configurable toolsets include `context`, `repos`, `issues`, `pull_requests`, `actions`, `code_security`, and others. Example tools include `get_me`, repository content lookup, issue operations, pull-request operations, and Actions inspection or triggering. The default toolsets are `context`, `repos`, `issues`, `pull_requests`, and `users`.
- **Permissions and credentials:** remote use supports OAuth or a GitHub Personal Access Token. Local use supports OAuth or `GITHUB_PERSONAL_ACCESS_TOKEN`. Available operations depend on token scopes such as repository access, `read:org`, or `security_events`.
- **Risk:** a broadly scoped token combined with write tools could let an agent expose private repository data or modify issues, pull requests, workflows, or other GitHub state.
- **Safety measure:** use the documented read-only mode, allow only the required tools or toolsets, and provide a fine-grained token limited to a disposable test repository. The server source/image, requested scopes, configuration, and tool list should be reviewed before each use, and credentials must never be committed.
## Example Output
The complete generated response is stored in `output/sample_agent_response.md`.
```markdown
# Study Recommendation
**Question:** I want to study Python decorators. What should I review first?
## Recommended Topic: Python Decorators
**Why it is relevant:** Decorators wrap callables to extend their behavior without changing their original implementation.
## Review First
- Python functions
- Local and enclosing scope
- Functions as first-class objects
```
## Known Limitations
- The catalog is a small static JSON file and must be edited manually.
- Search is keyword-based and does not understand synonyms or semantic meaning.
- The deterministic agent always selects the first ranked result and does not ask clarifying questions.
- The implementation uses local `stdio`; it does not provide authentication, multi-user isolation, or remote deployment.
- No LLM is used, so response wording follows a fixed Markdown template.
- Dataset validation checks required fields but does not deeply validate every field's value type.
## Reflection
**What problem does MCP solve?**
MCP replaces many one-off agent integrations with one protocol for capability discovery and structured communication. A compatible client can use different servers without directly importing their implementation code.
**What is the difference between an MCP tool and an MCP resource?**
A tool is called with arguments to execute a server-side function. A resource is read through a URI and provides read-only context. This project uses tools for search and exact lookup, while the compact catalog is a resource.
**What does this MCP server expose?**
It exposes the `search_topics` and `get_topic_details` tools plus the `topics://catalog` resource. All three capabilities read the local programming topic dataset without modifying it.
**How does the agent use the MCP server?**
The agent-like application creates an MCP client that launches the server as a subprocess. It calls `search_topics` with the student's question, calls `get_topic_details` with the selected id, and formats only the returned MCP data into a recommendation.
**What should be checked before using a third-party MCP server?**
Its publisher and source, local or remote execution model, exposed tools and resources, network and filesystem access, required scopes, credential storage, write or destructive operations, update policy, and whether its access can be restricted to the minimum needed.
**What limitation was observed in this implementation?**
Keyword ranking works for the included examples but cannot infer semantic relationships. A differently worded question may miss a relevant topic or rank a generic Python topic too highly.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessSyncing