Building and Automatically Testing a TCP MCP Server Using Python


Introduction
Have you ever thought about creating your own communication protocol for sending and receiving messages between systems? It might sound complex, but with the right tools and a clear guide, it’s completely achievable.
In this article, we’ll walk you through the process of building a basic TCP server in Python that uses the MCP (Message Communication Protocol) to handle structured message exchanges. But that’s not all—we’ll also show you how to set up automated testing with GitHub Actions. This means every time you make a change to your code, your server will be automatically tested to make sure everything still works correctly. It’s a great way to ensure your application remains stable and reliable over time.
What’s the Goal?
We want to:
Build a simple TCP server that understands basic MCP messages.
Create a test client to simulate user behavior.
Set up GitHub Actions to verify that everything works automatically.
The goal is not just to write code, but to ensure that it always works, thanks to automation.
Understanding the Protocol
MCP is an extremely simple message-response protocol. You can think of it as a rules-based text conversation between a client and a server.
Here's how the server should respond:
Received Command | Server Response |
PING | PONG |
HELLO | WELCOME TO MCP SERVER |
STATUS | SERVER STATUS: RUNNING OK |
INFO | MCP SERVER v1.0 - Python Implementation |
TEST | TEST SUCCESSFUL - Connection Working |
EXIT | GOODBYE - Closing Connection (and close) |
Anything else | ERROR: Unknown Command - Try PING, HELLO, STATUS, INFO, TEST, or EXIT |
Setting Up the TCP Server
Let’s start by writing a TCP server that listens for connections and responds based on our MCP logic.
import socket
HOST = '0.0.0.0'
PORT = 9001
def process_client(conn, address):
print(f"New client connected from {address}")
conn.sendall(b"=== MCP SERVER ONLINE ===\nAvailable commands: PING, HELLO, STATUS, INFO, TEST, EXIT\n")
while True:
data = conn.recv(1024)
if not data:
break
command = data.decode().strip().upper()
if command == "PING":
conn.sendall(b"PONG\n")
elif command == "HELLO":
conn.sendall(b"WELCOME TO MCP SERVER\n")
elif command == "STATUS":
conn.sendall(b"SERVER STATUS: RUNNING OK\n")
elif command == "INFO":
conn.sendall(b"MCP SERVER v1.0 - Python Implementation\n")
elif command == "TEST":
conn.sendall(b"TEST SUCCESSFUL - Connection Working\n")
elif command == "EXIT":
conn.sendall(b"GOODBYE - Closing Connection\n")
break
else:
conn.sendall(b"ERROR: Unknown Command - Try PING, HELLO, STATUS, INFO, TEST, or EXIT\n")
conn.close()
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server:
server.bind((HOST, PORT))
server.listen()
print(f"MCP Server running at {HOST}:{PORT}")
while True:
conn, addr = server.accept()
process_client(conn, addr)
This code:
Opens a TCP socket
Accepts incoming client connections
Responds based on MCP protocol rules
Simulating a Client for Testing
To make testing fast and repeatable, we’ll create a simple script that acts as a fake client. This script connects, sends commands, and prints what it gets back.
import socket
import time
HOST = 'localhost'
PORT = 9001
mcp_messages = ["PING", "HELLO", "STATUS", "INFO", "TEST", "UNKNOWN", "EXIT"]
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as client:
client.connect((HOST, PORT))
welcome = client.recv(1024)
print("[SERVER]:", welcome.decode().strip())
for msg in mcp_messages:
print(f"[CLIENT]: {msg}")
client.sendall((msg + "\n").encode())
reply = client.recv(1024)
print("[SERVER]:", reply.decode().strip())
time.sleep(0.5)
This client:
Connects to your server
Sends a fixed set of test messages
Displays the responses line-by-line
Running a Manual Test
To test manually:
In one terminal, start the server:
python mcp_server.py
In another terminal, run the client:
python mcp_client_auto.py
You should see responses like:
[SERVER]: === MCP SERVER ONLINE ===
[SERVER]: === MCP SERVER ONLINE ===
Available commands: PING, HELLO, STATUS, INFO, TEST, EXIT
[CLIENT]: PING
[SERVER]: PONG
[CLIENT]: PING
[SERVER]: PONG
[SERVER]: PONG
[CLIENT]: HELLO
[CLIENT]: HELLO
[SERVER]: WELCOME TO MCP SERVER
[CLIENT]: STATUS
[CLIENT]: STATUS
[SERVER]: SERVER STATUS: RUNNING OK
[CLIENT]: INFO
[SERVER]: MCP SERVER v1.0 - Python Implementation
[CLIENT]: TEST
[SERVER]: TEST SUCCESSFUL - Connection Working
[SERVER]: TEST SUCCESSFUL - Connection Working
[SERVER]: TEST SUCCESSFUL - Connection Working
[CLIENT]: UNKNOWN
[SERVER]: ERROR: Unknown Command - Try PING, HELLO, STATUS, INFO, TEST, or EXIT
[SERVER]: TEST SUCCESSFUL - Connection Working
[CLIENT]: UNKNOWN
[SERVER]: TEST SUCCESSFUL - Connection Working
[SERVER]: TEST SUCCESSFUL - Connection Working
[SERVER]: TEST SUCCESSFUL - Connection Working
[CLIENT]: UNKNOWN
[SERVER]: ERROR: Unknown Command - Try PING, HELLO, STATUS, INFO, TEST, or EXIT
[CLIENT]: EXIT
[SERVER]: GOODBYE - Closing Connection
Automating Tests with GitHub Actions
We don’t want to run this manually forever. With GitHub Actions, you can run the test every time you push code. Just create this file:
.github/workflows/mcp-test.yml
name: MCP
on: [push, pull_request]
jobs:
check-mcp:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Start MCP Server
run: |
python mcp_server.py &
sleep 2
- name: Run Test Client
run: python mcp_client_auto.py
With this setup:
The server starts in the background
The test client connects and runs
You get instant feedback in your GitHub Actions tab
GitHub Code
andresebast161616/MCP: Building and Automatically Testing a TCP MCP Server Using Python
Conclusion
This project demonstrates how you can build a basic yet functional TCP server in Python that follows a simple message protocol. By combining clear logic, a test client, and automated validation using GitHub Actions, you can ensure your server works reliably at all times. It’s a great starting point for anyone learning about sockets, protocols, and modern software testing practices.
Subscribe to my newsletter
Read articles from Andree Sebastian FLORES MELENDEZ directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
