This project demonstrates client authentication in Model Context Protocol (MCP) with a Python server and TypeScript client.
Out of the box, MCP v2025‑06‑18 provides no mechanism to verify which application is acting as the client. That leaves deployments vulnerable to misuse or malicious client implementations. Common use cases include:
- Only Claude‑signed “com.claude.desktop” is authorized on Claude.ai servers.
- Internal MCP servers only accept enterprise‑distributed tools.
- Local MCP instances restrict API access to approved tooling.
demo/
├── PyMcpServer/ # Python MCP Server with authentication
│ ├── server.py # Main server implementation
│ ├── clientAuth.py # Authentication logic
│ ├── public.pem # Public key for JWT verification
│ └── pyproject.toml # Python dependencies
└── TSMcpClient/ # TypeScript MCP Client
├── src/
│ ├── index.ts # Client entry point
│ ├── mcpClient.ts # Main client implementation
│ ├── clientAuth.ts # Client authentication logic
│ └── private.pem # Private key for JWT signing
└── package.json # Node.js dependencies
- Python 3.10+ with
uvpackage manager - Node.js 16+ with
npm - OpenSSL (for generating key pairs)
- Git (optional, for cloning)
This demo requires a private/public key pair for JWT authentication. The repository includes pre-generated keys, but you can generate your own using OpenSSL:
# Generate a 2048-bit RSA private key
openssl genrsa -out private.pem 2048# Extract the public key from the private key
openssl rsa -in private.pem -pubout -out public.pemAfter generating the keys:
- Place
private.peminTSMcpClient/src/(client directory) - Place
public.peminPyMcpServer/(server directory)
Security Note: In production, keep private keys secure and never commit them to version control. Consider using environment variables or secure key management systems.
Navigate to the server directory and start the server:
cd PyMcpServer
uv run server.pyThe server will start and listen for MCP connections. You should see output indicating the server is running.
In a new terminal, navigate to the client directory, install dependencies, and run the client:
cd TSMcpClient
npm install
npm run devAlternatively, you can build and run the compiled version:
npm run build
npm startThe Python server uses FastMCP and includes:
- JWT-based client authentication
- Public key verification
- Client metadata extraction
Available commands:
cd PyMcpServer
# Run the server directly
uv run server.py
# Run tests
uv run test_server.py
# Install dependencies
uv syncThe TypeScript client is a CLI application that:
- Connects to the MCP server
- Handles JWT authentication
- Demonstrates client-server communication
Available commands:
cd TSMcpClient
# Development mode (with hot reload)
npm run dev
# Build the project
npm run build
# Run the built version
npm start
# Watch mode for development
npm run watch
# Debug mode
npm run debug
# Linting
npm run lint
npm run lint:fix
# Clean build artifacts
npm run cleanThis demo uses JWT (JSON Web Tokens) for client authentication:
- The client signs JWTs using a private key (
TSMcpClient/src/private.pem) - The server verifies JWTs using the corresponding public key (
PyMcpServer/public.pem) - Authentication is performed during the MCP initialization handshake
The server includes a Dockerfile for containerized deployment:
cd PyMcpServer
docker build -t mcp-server .
docker run -p 8000:8000 mcp-server- Server fails to start: Ensure Python 3.10+ and
uvare installed - Client connection fails: Verify the server is running and accessible
- Authentication errors: Check that public/private key pairs match
- Port conflicts: The server may use different ports; check server output
- Use
npm run debugfor client-side debugging - Check server logs for authentication details
- Verify JWT token generation and validation
PyMcpServer/server.py- Main server implementationPyMcpServer/clientAuth.py- JWT verification logicTSMcpClient/src/mcpClient.ts- Client implementationTSMcpClient/src/clientAuth.ts- JWT signing logic