Skip to main content
Glama
Kanchan-Baran-Hazra

FastMCP SMS Server

README.md
# ๐Ÿ“ฑ 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

---

## ๐Ÿ—๏ธ Architecture

```text
                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚    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

```text
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

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

---

## 2. Create a virtual environment

### Windows

```powershell
python -m venv .venv
```

Activate it:

```powershell
.venv\Scripts\activate
```

### Linux / macOS

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

---

## 3. Install dependencies

```bash
pip install -r requirements.txt
```

---

# ๐Ÿ” Generate RSA Keys

This project uses **RS256**.

The authentication server signs JWTs using the private key:

```text
private_key.pem
```

The MCP server verifies them using:

```text
public_key.pem
```

Generate a key pair with OpenSSL:

```bash
openssl genrsa -out keys/private_key.pem 2048
```

Then:

```bash
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:

```text
POST /register
POST /login
```

Start it with:

```powershell
uvicorn auth_server.main:app --port 9000
```

The authentication server will run at:

```text
http://127.0.0.1:9000
```

---

# ๐Ÿ“ Register a User

Example:

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

Response:

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

---

# ๐Ÿ”‘ Login

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

Response:

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

The JWT contains claims such as:

```json
{
  "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.

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

The authentication flow is:

```text
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:

```python
db = SessionLocal()
```

Example:

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

user = db.scalar(stmt)
```

The session is closed after the operation:

```python
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:

```python
token = get_access_token()

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

Then SQLAlchemy can find the user:

```python
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:

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

The client only needs to provide:

```text
recipient
message
```

It does **not** need to provide:

```text
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:

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

The configuration file is located at:

```text
%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`:

```gitignore
.venv/
__pycache__/
*.pyc

.env
.env.*

users.db

keys/private_key.pem

*.log
```

Never commit:

```text
private_key.pem
```

or:

```text
TextBee API keys
JWT secrets
database passwords
```

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

---

# ๐Ÿ”„ Current Authentication Flow

```text
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚     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:

```powershell
uvicorn auth_server.main:app --port 9000
```

Start the MCP server:

```powershell
python mcp_server.py
```

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

---

# ๐Ÿšง Roadmap

* [x] FastMCP server
* [x] FastAPI authentication server
* [x] User registration
* [x] User login
* [x] JWT authentication
* [x] RS256 signing
* [x] SQLAlchemy integration
* [x] Authenticated user lookup
* [x] TextBee SMS integration
* [x] 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:

```text
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.