PythonJokesMCP
No description available
Ask AI about PythonJokesMCP
Powered by Claude Β· Grounded in docs
I know everything about PythonJokesMCP. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
MCP Jokes Server with NBDev
A complete example of building and deploying a Model Context Protocol (MCP) server using NBDev for notebook-driven development and Railway for deployment.
This project demonstrates how to create MCP tools that can be integrated with Claude Code, providing joke functionality through a clean, maintainable NBDev workflow.
What You'll Build
An MCP server with 4 joke tools:
- Chuck Norris jokes (random and by category)
- Dad jokes
- Category listings
Live Demo: https://web-production-4336b.up.railway.app/mcp
Quick Start
1. Clone and Setup
git clone https://github.com/DavidFarrell/PythonJokesMCP.git
cd PythonJokesMCP
pip install -r requirements.txt
pip install -e .
2. Test Locally
python -m mcp_jokes.transport
# Server starts on http://localhost:8000/mcp
3. Add to Claude Code
claude mcp add jokes https://web-production-4336b.up.railway.app/mcp --transport http
NBDev Workflow
This project follows the notebook-driven development approach:
Project Structure
βββ nbs/ # π Notebooks (source of truth)
β βββ 01_http_clients.ipynb # HTTP client functions
β βββ 02_server.ipynb # FastMCP server setup
β βββ 03_transport.ipynb # Server startup and deployment
βββ mcp_jokes/ # π Generated Python package
β βββ clients.py # Auto-generated from notebooks
β βββ server.py # Auto-generated from notebooks
β βββ transport.py # Auto-generated from notebooks
βββ settings.ini # NBDev configuration
Development Process
- Edit Notebooks: Make changes in
nbs/*.ipynbfiles - Export Code: Run
nbdev_exportto generate Python files - Test Locally: Run
python -m mcp_jokes.transport - Deploy: Push to Railway for automatic deployment
# Development cycle
vim nbs/02_server.ipynb # Edit notebooks
nbdev_export # Generate Python files
python -m mcp_jokes.transport # Test locally
git add . && git commit -m "..." # Deploy to Railway
Key NBDev Concepts
Export Directives
Mark cells for export to Python modules:
#| default_exp server # Sets the target module
#| export # Exports this cell's content
Critical Pattern: Main Guard
Essential for Railway deployment:
#| export
def main():
# Server startup code
pass
#| export # β CRITICAL: Must export the main guard!
if __name__ == "__main__":
main()
Railway Deployment
Configuration Files
Procfile:
web: python -m mcp_jokes.transport
pyproject.toml (auto-generated by NBDev):
[project]
name = "mcp_jokes"
dependencies = [
"mcp[http]>=1.0.0",
"httpx>=0.25.0",
"uvicorn[standard]>=0.24.0"
]
Deployment Process
- Push to GitHub: Railway auto-deploys from main branch
- Railway Build: Installs package with
pip install . - Railway Start: Runs
python -m mcp_jokes.transport - Package Import: Uses absolute imports (
from mcp_jokes.clients import)
Building Your Own MCP Server
1. Initialize NBDev Project
# Create new project
mkdir my-mcp-server && cd my-mcp-server
pip install nbdev
# Initialize
nbdev_new
2. Configure for MCP
Edit settings.ini:
[DEFAULT]
lib_name = my_mcp_server
requirements = mcp[http] httpx uvicorn starlette
3. Create MCP Tools Notebook
Create nbs/01_server.ipynb:
#| default_exp server
#| export
from mcp.server import FastMCP
#| export
def create_mcp_server(port: int = 8000):
mcp = FastMCP(
name="my-mcp-server",
host="0.0.0.0",
port=port,
streamable_http_path="/mcp"
)
@mcp.tool()
async def my_tool() -> str:
"""My custom MCP tool"""
return "Hello from my MCP server!"
return mcp
4. Create Transport Notebook
Create nbs/02_transport.ipynb:
#| default_exp transport
#| export
import os
from my_mcp_server.server import create_mcp_server
#| export
def main():
port = int(os.environ.get("PORT", 8000))
mcp = create_mcp_server(port)
mcp.run(transport="streamable-http")
#| export # β ESSENTIAL!
if __name__ == "__main__":
main()
5. Generate and Test
nbdev_export # Generate Python files
python -m my_mcp_server.transport # Test locally
Best Practices
β Do
- Use absolute imports in notebooks (
from my_package.module import) - Export the main guard with
#| exportdirective - Test locally before deploying with
python -m package.transport - Keep notebooks as source of truth - never edit generated
.pyfiles
β Don't
- Edit generated Python files directly (they get overwritten)
- Use relative imports in notebooks (NBDev handles conversion)
- Forget to export the
if __name__ == "__main__":guard - Skip local testing before deployment
Troubleshooting
Common Issues
HTTP 502 on Railway: Usually means the __main__ guard wasn't exported
# Fix: Add #| export before the main guard
#| export
if __name__ == "__main__":
main()
Import Errors: Package not installed properly
# Fix: Install in development mode
pip install -e .
NBDev Export Fails: Check settings.ini configuration
# Ensure these match your project
lib_name = your_package_name
lib_path = your_package_name
Integration with Claude Code
Once deployed, add your server to Claude Code:
claude mcp add myserver https://your-railway-app.railway.app/mcp --transport http
Your tools will then be available in Claude Code sessions!
Learn More
- MCP Documentation: Model Context Protocol
- NBDev Documentation: NBDev Guide
- FastMCP: MCP Server Framework
- Railway: Railway Deployment
License
MIT License - feel free to use this as a template for your own MCP servers!
