Every tool in the East Africa coordination infrastructure stack started from the same scaffold. Here's exactly how to build and publish one yourself.
What You're Building
An MCP server is a Python package that exposes tools to AI assistants. When a user installs it and connects it to Claude, the AI can call your tools as naturally as answering a question.
pip install your-mcp-server
# Then Claude can:
# "Check NHIF coverage for outpatient surgery" → calls your tool → returns structured result
Step 1: Set Up the Project (2 min)
your-mcp-server/
├── src/
│ └── your_package/
│ ├── __init__.py
│ └── main.py
├── pyproject.toml
├── README.md
└── .github/
└── workflows/
└── publish.yml
mkdir your-mcp-server && cd your-mcp-server
mkdir -p src/your_package
touch src/your_package/__init__.py src/your_package/main.py
Step 2: Write Your Tool (10 min)
# src/your_package/main.py
from __future__ import annotations
from typing import Annotated
from fastmcp import FastMCP
mcp = FastMCP(
name="your-mcp-server",
instructions="Describe what your server does in one paragraph.",
)
@mcp.tool(
description=(
"What this tool does in plain language. "
"Include the Western parallel if applicable. "
"Note if it uses DEMO data."
)
)
def your_tool(
param1: Annotated[str, "Description of param1"],
param2: Annotated[int, "Description of param2"] = 0,
) -> dict:
# Your logic here
return {
"result": f"Processed {param1}",
"note": "DEMO — replace with real data source in production",
"source": "your-mcp-server",
}
def main():
mcp.run()
if __name__ == "__main__":
main()
Step 3: Configure pyproject.toml (3 min)
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta" # ← exact string, no variation
[project]
name = "your-mcp-server"
version = "0.1.0"
description = "One-line description"
authors = [{name = "Your Name", email = "you@example.com"}]
license = {text = "MIT"}
readme = "README.md"
requires-python = ">=3.9"
dependencies = ["fastmcp>=2.0.0"]
[project.scripts]
your-mcp-server = "your_package.main:main" # CLI entry point
[tool.setuptools.packages.find]
where = ["src"] # ← required for src/ layout
Common mistake: build-backend = "setuptools.backends.legacy:build" is not valid. Use exactly "setuptools.build_meta". This error causes python -m build to fail silently in CI.
Step 4: Set Up CI Publishing (5 min)
Option A: API Token (faster)
- Create a PyPI API token at pypi.org/manage/account/#api-tokens
- Add as
PYPI_API_TOKENin your GitHub repo → Settings → Secrets
Option B: OIDC Trusted Publisher (more secure, recommended)
- Create the package on PyPI first (one push via token)
- Go to
pypi.org/manage/project/{name}/settings/publishing/ - Add GitHub Actions publisher: owner, repo,
publish.yml, environmentpypi
.github/workflows/publish.yml:
name: Publish to PyPI
on:
push:
tags: ["v*"]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: {python-version: "3.11"}
- run: pip install build
- run: python -m build
- uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_API_TOKEN }}
Step 5: Publish (2 min)
git init && git add . && git commit -m "initial commit"
git remote add origin https://github.com/yourusername/your-mcp-server
git push -u origin main
git tag v0.1.0 && git push origin v0.1.0
# → GitHub Actions runs → pip install your-mcp-server works in 2-3 minutes
Step 6: Connect to Claude (1 min)
# Install
pip install your-mcp-server
# Add to Claude Code
claude mcp add myserver -- your-mcp-server
# Test
claude "Use myserver to process X"
East Africa Design Patterns
A few patterns specific to building for this context:
Trust integrity:
return {
"result": result,
"note": "DEMO — Synthetic data for educational purposes. Not operational guidance.",
"source": "your-mcp-server. Research basis: [cite your source]",
}
Swahili/English bilingual errors:
except Exception as e:
return {"error": f"Hitilafu / Error: {str(e)[:60]}. Jaribu tena / Try again."}
Version bump workflow:
# Edit pyproject.toml → version = "0.2.0"
git commit -am "bump: v0.2.0"
git tag v0.2.0 && git push origin main --tags
That's the complete cycle. Every MCP server in the East Africa coordination stack was built and published with exactly this scaffold.
Full portfolio and all 12 packages: gabrielmahia.github.io
Top comments (0)