Building and Testing a TCP MCP Server in Python – With Automated CI Magic!


Introduction

Ever wanted to build your own communication protocol and know for sure it works every single time?
Welcome to the world of MCP (Message Communication Protocol)—and to a project where we combine simple Python, a sprinkle of automation, and a dash of fun!

This isn’t just a dry technical walkthrough. By the end, you’ll have a robust little server, a robot client, and the power of GitHub Actions making sure your code stays unbreakable. Ready to get your hands dirty?


What is MCP?

MCP stands for Message Communication Protocol. Think of it as two people (well, programs) sending each other simple notes:

  • When someone says “PING”, you say “PONG”.

  • They say “HELLO”, you say “WELCOME”.

  • They say “EXIT”, you say “BYE”.

  • Anything else? “UNKNOWN COMMAND!”

It’s so basic, you could explain it to your grandma. But that’s what makes it perfect for learning—and for building reliable networked applications.


Why Should You Care?

Because testing network code is usually a pain!

  • Manual tests are boring.

  • Mistakes slip in.

  • You want confidence, not guesswork!

With a few Python scripts and a pinch of CI/CD (Continuous Integration/Continuous Delivery), you can automate everything—so your MCP server is always ready to serve, and you can focus on building cool stuff.


Project Overview

Here’s what you get:

FileWhat it does
mcp_server.pyYour friendly MCP server
mcp_client_auto.pyA robot client to test your server
.github/workflows/test-mcp.ymlThe magic that runs tests on every push

Step 1: The MCP Server, Explained Simply

Let’s peek behind the curtain: How does the server work?

import socket

HOST = '0.0.0.0'
PORT = 8765

def handle_client(conn, addr):
    print(f"[+] New connection from {addr}")
    conn.sendall(b"WELCOME TO MCP SERVER\n")
    try:
        while True:
            data = conn.recv(1024)
            if not data:
                print(f"[-] {addr} disconnected")
                break
            msg = data.decode().strip().upper()
            print(f"[{addr}] Received: {msg}")
            if msg == "PING":
                conn.sendall(b"PONG\n")
            elif msg == "HELLO":
                conn.sendall(b"WELCOME\n")
            elif msg == "EXIT":
                conn.sendall(b"BYE\n")
                break
            else:
                conn.sendall(b"UNKNOWN COMMAND\n")
    finally:
        conn.close()

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind((HOST, PORT))
    s.listen()
    print(f"[*] MCP Server listening on {HOST}:{PORT}")
    while True:
        conn, addr = s.accept()
        handle_client(conn, addr)
  • Listens for connections

  • Responds to commands

  • Closes politely when told

Simple, elegant, and easy to understand.


Step 2: A Client That Never Sleeps

Testing by hand? No, thank you! Meet your new automated client:

import socket
import time

HOST = 'localhost'
PORT = 8765

commands = ['PING', 'HELLO', 'UNKNOWN', 'EXIT']

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((HOST, PORT))
    welcome = s.recv(1024)
    print("[SERVER]:", welcome.decode().strip())
    for cmd in commands:
        print(f"[CLIENT]: {cmd}")
        s.sendall(f"{cmd}\n".encode())
        response = s.recv(1024)
        print("[SERVER]:", response.decode().strip())
        time.sleep(1)

This little program:

  • Connects to your server

  • Fires off commands

  • Checks the responses

  • Never gets tired or forgets a step


Step 3: Test It Yourself!

🏁 Ready to try?

Step 1: Start the server (in one terminal):

python mcp_server.py

Step 2: Run the client (in another terminal):

python mcp_client_auto.py

You’ll see a conversation like this:

[SERVER]: WELCOME TO MCP SERVER
[CLIENT]: PING
[SERVER]: PONG
[CLIENT]: HELLO
[SERVER]: WELCOME
[CLIENT]: UNKNOWN
[SERVER]: UNKNOWN COMMAND
[CLIENT]: EXIT
[SERVER]: BYE

Voilà! You’ve just run your own protocol test.


Step 4: Automate Your Life with GitHub Actions

Why stop at local testing?
With GitHub Actions, you can have your code tested automatically—every push, every pull request, every time.

Here’s the magic workflow (.github/workflows/test-mcp.yml):

name: Test MCP Server

on: [push, pull_request]

jobs:
  test-mcp:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.10'
      - name: Start MCP Server (in the background)
        run: |
          python mcp_server.py &
          sleep 2
      - name: Run automated MCP client
        run: python mcp_client_auto.py

Now every time you push your code, GitHub:

  • Spawns a server

  • Runs the client

  • Checks that everything works

Check the Actions tab in your repo for instant feedback!


Why Automate?

  • No more “works on my machine” excuses

  • Instant feedback if you break something

  • Peace of mind before merging code

  • More time to build cool features


Source Code

You can find the complete source code for this project on GitHub:

https://github.com/jf2021070309/mcp-server-python

Real Demo

Here’s a YouTube video where I talk about the real demo:


Conclusion

This project shows how easy and effective it can be to build, test, and automate a TCP MCP server in Python—with continuous integration ensuring reliability at every step. With just a few scripts and GitHub Actions, you gain both hands-on learning and the confidence that your code will always work as expected.

Try out this example, and let me know your thoughts or questions in the comments!

0
Subscribe to my newsletter

Read articles from JAIME ELIAS FLORES QUISPE directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

JAIME ELIAS FLORES QUISPE
JAIME ELIAS FLORES QUISPE