Skip to main content
Glama
Kanchan-Baran-Hazra

FastMCP SMS Server

πŸ“± FastMCP SMS Server

A production-oriented Model Context Protocol (MCP) server built with FastMCP, JWT authentication, SQLAlchemy, and the TextBee SMS API.

This project demonstrates how an MCP server can authenticate users, identify the authenticated user from a JWT, access user-specific data through SQLAlchemy, and expose SMS functionality as an MCP tool.


✨ Features

  • πŸ”Œ FastMCP server

  • πŸ” JWT authentication with RS256

  • πŸ”‘ Public/private RSA key verification

  • πŸ‘€ User registration and login

  • πŸ—„οΈ SQLAlchemy database integration

  • 🎫 Access token based authentication

  • πŸ§‘β€πŸ’» Authenticated user identification using JWT sub

  • πŸ“± Send SMS through TextBee

  • πŸ”’ User-specific API credentials

  • πŸ€– MCP client support

  • πŸ–₯️ Claude Desktop integration

  • ⚑ FastAPI authentication server


Related MCP server: Sms Verify3 MCP Server

πŸ—οΈ Architecture

                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚    Claude Desktop   β”‚
                    β”‚     MCP Client      β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                               β”‚
                               β”‚ MCP
                               β–Ό
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚    FastMCP Server   β”‚
                    β”‚                     β”‚
                    β”‚  JWT Verification   β”‚
                    β”‚  MCP Tools         β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                               β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚                     β”‚
                    β–Ό                     β–Ό
             β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
             β”‚  SQLAlchemy β”‚       β”‚   TextBee    β”‚
             β”‚  Database   β”‚       β”‚   SMS API    β”‚
             β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β–²
                    β”‚
                    β”‚ user_id
                    β”‚
             β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
             β”‚ JWT Token   β”‚
             β”‚             β”‚
             β”‚ sub         β”‚
             β”‚ username    β”‚
             β”‚ scope       β”‚
             β”‚ iss         β”‚
             β”‚ aud         β”‚
             β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“‚ Project Structure

mcp/
β”‚
β”œβ”€β”€ src/
β”‚   β”‚
β”‚   β”œβ”€β”€ auth_server/
β”‚   β”‚   β”œβ”€β”€ __init__.py
β”‚   β”‚   β”œβ”€β”€ main.py
β”‚   β”‚   β”œβ”€β”€ database.py
β”‚   β”‚   β”œβ”€β”€ models.py
β”‚   β”‚   β”œβ”€β”€ schemas.py
β”‚   β”‚   └── security.py
β”‚   β”‚
β”‚   β”œβ”€β”€ mcp_server.py
β”‚   β”œβ”€β”€ mcp_database.py
β”‚   └── client.py
β”‚
β”œβ”€β”€ keys/
β”‚   β”œβ”€β”€ private_key.pem
β”‚   └── public_key.pem
β”‚
β”œβ”€β”€ .gitignore
β”œβ”€β”€ requirements.txt
└── README.md

Never commit private_key.pem or real API credentials to GitHub.


πŸ› οΈ Technologies

Technology

Purpose

Python

Backend

FastMCP

MCP server

FastAPI

Authentication server

SQLAlchemy

Database ORM

SQLite

Development database

PyJWT

JWT creation and verification

Cryptography

RSA cryptography

Pwdlib

Password hashing

HTTPX

HTTP requests

TextBee

SMS delivery


πŸš€ Installation

1. Clone the repository

git clone https://github.com/YOUR_USERNAME/YOUR_REPOSITORY.git
cd YOUR_REPOSITORY

2. Create a virtual environment

Windows

python -m venv .venv

Activate it:

.venv\Scripts\activate

Linux / macOS

python3 -m venv .venv
source .venv/bin/activate

3. Install dependencies

pip install -r requirements.txt

πŸ” Generate RSA Keys

This project uses RS256.

The authentication server signs JWTs using the private key:

private_key.pem

The MCP server verifies them using:

public_key.pem

Generate a key pair with OpenSSL:

openssl genrsa -out keys/private_key.pem 2048

Then:

openssl rsa \
  -in keys/private_key.pem \
  -pubout \
  -out keys/public_key.pem

On Windows PowerShell, the same commands can be run if OpenSSL is installed.


πŸ‘€ Authentication Server

The authentication server provides:

POST /register
POST /login

Start it with:

uvicorn auth_server.main:app --port 9000

The authentication server will run at:

http://127.0.0.1:9000

πŸ“ Register a User

Example:

curl.exe -X POST http://127.0.0.1:9000/register `
  -H "Content-Type: application/json" `
  -d '{\"username\":\"kanchan\",\"password\":\"1234\"}'

Response:

{
  "message": "User created successfully",
  "user_id": 1,
  "username": "kanchan"
}

πŸ”‘ Login

curl.exe -X POST http://127.0.0.1:9000/login `
  -H "Content-Type: application/json" `
  -d '{\"username\":\"kanchan\",\"password\":\"1234\"}'

Response:

{
  "access_token": "YOUR_JWT_TOKEN",
  "token_type": "bearer"
}

The JWT contains claims such as:

{
  "sub": "1",
  "username": "kanchan",
  "scope": "profile:read",
  "iss": "http://localhost:9000",
  "aud": "my-mcp-server",
  "iat": 1234567890,
  "exp": 1234571490
}

πŸ” JWT Authentication

The MCP server uses an RSA public key to verify the JWT.

verifier = JWTVerifier(
    public_key=PUBLIC_KEY,
    issuer="http://localhost:9000",
    audience="my-mcp-server",
    algorithm="RS256",
)

The authentication flow is:

User
 β”‚
 β”‚ username + password
 β–Ό
Auth Server
 β”‚
 β”‚ signs JWT with private key
 β–Ό
Access Token
 β”‚
 β–Ό
MCP Client
 β”‚
 β”‚ Bearer token
 β–Ό
FastMCP
 β”‚
 β”‚ verifies signature with public key
 β–Ό
MCP Tool

πŸ—„οΈ SQLAlchemy Integration

The MCP tools use SQLAlchemy to access the database.

A database session is created using:

db = SessionLocal()

Example:

stmt = select(User).where(User.id == user_id)

user = db.scalar(stmt)

The session is closed after the operation:

finally:
    db.close()

πŸ‘€ Getting the Authenticated User

The MCP server does not need the client to provide a user_id.

Instead, the user ID comes from the verified JWT:

token = get_access_token()

user_id = int(token.claims["sub"])

Then SQLAlchemy can find the user:

stmt = select(User).where(User.id == user_id)

user = db.scalar(stmt)

This gives the MCP server the identity of the user who made the request.


πŸ“± Send SMS Tool

The project exposes an MCP tool similar to:

@mcp.tool()
def send_sms(
    recipient: str,
    message: str,
) -> dict:
    ...

The client only needs to provide:

recipient
message

It does not need to provide:

user_id
api_key
device_id

The server can determine the authenticated user from the JWT and retrieve that user's TextBee configuration from the database.


πŸ€– Claude Desktop

The MCP server can be connected to Claude Desktop as a local MCP server.

Example configuration:

{
  "mcpServers": {
    "my-mcp-server": {
      "command": "E:\\mcp\\.venv\\Scripts\\python.exe",
      "args": [
        "E:\\mcp\\src\\mcp_server.py"
      ]
    }
  }
}

The configuration file is located at:

%APPDATA%\Claude\claude_desktop_config.json

After modifying the configuration, restart Claude Desktop.

Your MCP tools should then become available to Claude.


⚠️ Security

Do not commit secrets to GitHub.

Add the following to .gitignore:

.venv/
__pycache__/
*.pyc

.env
.env.*

users.db

keys/private_key.pem

*.log

Never commit:

private_key.pem

or:

TextBee API keys
JWT secrets
database passwords

For production, store secrets in environment variables or a dedicated secrets manager.


πŸ”„ Current Authentication Flow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚     User     β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
       β”‚ Login
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Auth Server     β”‚
β”‚    FastAPI       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚
         β”‚ RS256 JWT
         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   MCP Client     β”‚
β”‚ Claude / Custom  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚
         β”‚ Access Token
         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  FastMCP Server  β”‚
β”‚                  β”‚
β”‚ JWTVerifier      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚
         β”‚ Verified JWT
         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚    MCP Tool      β”‚
β”‚                  β”‚
β”‚ get_access_token β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚
         β”‚ sub β†’ user_id
         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚    SQLAlchemy    β”‚
β”‚                  β”‚
β”‚      User        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚
         β”‚ User credentials
         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚     TextBee      β”‚
β”‚    SMS Gateway   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ§ͺ Development

Start the authentication server:

uvicorn auth_server.main:app --port 9000

Start the MCP server:

python mcp_server.py

For Claude Desktop, configure the MCP server using the stdio transport.


🚧 Roadmap

  • FastMCP server

  • FastAPI authentication server

  • User registration

  • User login

  • JWT authentication

  • RS256 signing

  • SQLAlchemy integration

  • Authenticated user lookup

  • TextBee SMS integration

  • Claude Desktop local integration

  • OAuth 2.0 authorization server

  • Multi-user TextBee credential management

  • PostgreSQL support

  • Refresh tokens

  • Token revocation

  • Production deployment

  • HTTPS

  • Rate limiting

  • Audit logging


πŸ“š What This Project Demonstrates

This project is primarily a learning and development example for understanding how the following technologies work together:

MCP
 +
FastMCP
 +
JWT
 +
RS256
 +
FastAPI
 +
SQLAlchemy
 +
External APIs

The main goal is to demonstrate how an MCP tool can securely identify the authenticated user and perform user-specific operations.


πŸ“„ License

This project is available under the MIT License.

See LICENSE for details.


⭐ Contributing

Contributions, suggestions, and improvements are welcome.

If you find a bug or have an idea, feel free to open an issue or submit a pull request.

Related MCP Connectors

Related MCP Servers