Skip to main content
Glama
ahmad-act

MCP Server with Authentication

by ahmad-act
README.md
# ๐Ÿš€ MCP Server with Authentication and Testing with Inspector

This project implements a Model Context Protocol (MCP) server with two authentication mechanisms: API Key Authentication and JWT (JSON Web Token) Authentication. It provides a robust framework for handling authenticated requests with comprehensive error handling and logging, suitable for production environments. The server supports tools like `echo`, `login`, `secure_action`, and `admin_action`, with authentication enforced where required.

# ๐Ÿ“š Table of Contents

1. [๐Ÿš€ Project Overview](#-mcp-server-with-authentication-and-testing-with-inspector)

2. [๐ŸŽฏ Purpose](#-purpose)

3. [โœจ Features](#-features)

4. [๐Ÿ—‚๏ธ Project Structure](#-project-structure)

5. [โœ… Prerequisites](#-prerequisites)

6. [โš™๏ธ Installation](#-installation)
   - [๐Ÿ“ฅ Clone the Repository](#-clone-the-repository)
   - [๐Ÿช„ Set Up a Virtual Environment](#-set-up-a-virtual-environment-recommended)
   - [๐Ÿ“ฆ Install Dependencies](#-install-dependencies)

7. [๐Ÿงฉ Packages](#-packages)

8. [๐Ÿšฆ Usage](#-usage)
   - [1๏ธโƒฃ MCP Server with Stdio and API Key](#-mcp-server-with-stdio-and-api-key-mcp-server-with-stdio-api-key-authpy)
     - [โ–ถ๏ธ Run the MCP Server](#๏ธ-run-the-mcp-server)
     - [โ–ถ๏ธ Run the MCP Inspector](#-run-the-mcp-inspector)
     - [๐ŸŒ Open the MCP Inspector](#-open-the-mcp-inspector)
     - [๐Ÿงช Using the MCP Inspector](#-using-the-mcp-inspector)
   - [2๏ธโƒฃ MCP Server with Stdio and JWT](#-mcp-server-with-stdio-and-jwt-mcp-server-with-stdio-jwt-key-authpy)
     - [โ–ถ๏ธ Run the MCP Server](#๏ธ-run-the-mcp-server-1)
     - [โ–ถ๏ธ Run the MCP Inspector](#-run-the-mcp-inspector-1)
     - [๐ŸŒ Open the MCP Inspector](#-open-the-mcp-inspector-1)
     - [๐Ÿงช Using the MCP Inspector](#-using-the-mcp-inspector-1)
   - [3๏ธโƒฃ MCP Server with Stdio and Auth2 (To Do)](#-mcp-server-with-stdio-and-auth2-mcp-server-with-stdio-auth2-authpy)

9. [๐Ÿ”„ Workflow](#-workflow)

10. [๐Ÿฉต Troubleshooting](#-troubleshooting)
   - [๐Ÿšซ Invalid API Key](#-invalid-api-key)
   - [โš ๏ธ Invalid JWT Token](#-invalid-jwt-token)
   - [๐Ÿ”’ Permission Errors](#-permission-errors)
   - [๐Ÿ“ Log Files](#-log-files)

## ๐ŸŽฏ Purpose

The purpose of this project is to demonstrate secure MCP server implementations with two distinct authentication methods:
- ๐Ÿ”‘ **API Key Authentication**: Validates requests using predefined API keys.
- ๐Ÿ›ก๏ธ **JWT Authentication**: Uses JSON Web Tokens for user authentication and permission-based access control.

This project is designed for developers who need a secure, scalable, and extensible MCP server with robust debugging and logging capabilities.

## โœจ Features

- ๐Ÿ”‘ **API Key Authentication**:
  - Validates requests using a set of predefined API keys.
  - Supports key extraction from arguments, metadata, or environment variables.
  - Simple `echo` tool for demonstration.

- ๐Ÿ›ก๏ธ **JWT Authentication**:
  - Supports user authentication via username/password to generate JWT tokens.
  - Enforces permission-based access control (`read`, `write`, `admin`).
  - Includes tools: `login`, `echo`, `secure_action`, and `admin_action`.
  - Configurable token expiry (default: 24 hours).
  - Token extraction from arguments, metadata, or environment variables.

- โš ๏ธ **Robust Error Handling**:
  - Custom `McpError` for consistent error responses.
  - Detailed logging of errors and server events.

- ๐Ÿ“ **Logging**:
  - Configurable logging to both console and rotating log files.
  - Log rotation based on file size (5MB, with 5 backups).
  - Automatic cleanup of old log files based on age.

- ๐Ÿ” **MCP Inspector Integration**:
  - Compatible with MCP Inspector for testing and debugging.
  - Supports debugging via `--debug` flag.

## ๐Ÿ—‚๏ธ Project Structure

```plaintext
/
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ config/
โ”‚   โ”‚   โ”œโ”€โ”€ __init__.py
โ”‚   โ”‚   โ”œโ”€โ”€ app_settings.py                     # Configuration for environment variables and settings
โ”‚   โ”‚   โ””โ”€โ”€ logging_config.py                   # Logging setup with file rotation
โ”‚   โ”œโ”€โ”€ mcp-server-with-stdio-api-key-auth.py   # API Key Authentication server
โ”‚   โ”œโ”€โ”€ mcp-server-with-stdio-auth2-auth.py     # To Do
โ”‚   โ””โ”€โ”€ mcp-server-with-stdio-jwt-key-auth.py   # JWT Authentication server
โ”œโ”€โ”€ pyproject.toml                              # Project documentation
โ””โ”€โ”€ README.md                                   # Python dependencies
```

## โœ… Prerequisites

- **Python**: Version 3.13 or higher
- **uv**: Used for managing Python virtual environments
- **Node.js**: Required for running MCP Inspector
- **NPM**: Required to run MCP Inspector
- **Operating System**: Windows, macOS, or Linux

## โš™๏ธ Installation

1. ๐Ÿ“ฅ **Clone the Repository**:
   ```bash
   git clone https://github.com/ahmad-act/MCP-Server-with-Authentication-and-Testing-with-Inspector.git
   cd MCP-Server-with-Authentication-and-Testing-with-Inspector
   ```

2. ๐Ÿช„ **Set Up a Virtual Environment** (recommended):
   ```bash
   uv venv
   source venv/bin/activate  # On Windows: venv\Scripts\activate
   ```

3. ๐Ÿ“ฆ **Install Dependencies**:
   ```bash
   uv sync
   ```
---

## ๐Ÿงฉ Packages

The following Python packages are required:

```plaintext
mcp[cli]>=1.10.1
PyJWT>=2.8.0
python-dotenv>=1.0.0
```

๐Ÿ‘‰ Install them using:

```bash
uv add mcp[cli] PyJWT python-dotenv
```

## ๐Ÿšฆ Usage

### 1๏ธโƒฃ MCP Server with Stdio and API Key (`mcp-server-with-stdio-api-key-auth.py`)

#### โ–ถ๏ธ **Run the MCP Server**:

โš ๏ธ *You do not need to manually run the MCP server for stdio transport. MCP Inspector runs the MCP Server for stdio transport.*

#### โ–ถ๏ธ **Run the MCP Inspector**:

The `stdio` server is typically launched by the MCP Inspector, not manually. Run the Inspector with the following command, add `-e` environment variable and adjusting the `--directory` path to your `src/` directory:

```bash
npx @modelcontextprotocol/inspector uv -e MCP_API_KEY=sk-1234567890abcdef --directory '<your-src-directory>/src' run mcp-server-with-stdio-api-key-auth.py --debug
```

![MCP Inspector Run](doc/mcp-inspector-stdio-api-key-run-1.png)

#### ๐ŸŒ **Open the MCP Inspector**:

Open the link `http://localhost:6274/?MCP_PROXY_AUTH_TOKEN=XXXXXXXXXXXXXXXXXX` with its token in your browser:

![MCP Inspector Use](doc/mcp-inspector-stdio-api-key-open-1.png)

#### ๐Ÿงช **Using the MCP Inspector**

1. After running the above command, the Inspector will start and automatically connect to the `stdio`-based server.
2. In the Inspector UI (`http://127.0.0.1:6274`), inspect the available tools (e.g., `echo`).
3. Test the `echo` tool:

   - **Input**:

   ```json
   {
     "method": "call_tool",
     "params": {
       "name": "echo",
       "arguments": {
         "message": "test",
         "_api_key": "sk-1234567890abcdef"
       }
     }
   }
   ```

   **Expected Response**:

   ```json
   {
     "result": [
       {
         "type": "text",
         "text": "Echo: test"
       }
     ]
   }
   ```

   ![MCP Inspector Use](doc/mcp-inspector-stdio-api-key-use-1.png)
   ![MCP Inspector Use](doc/mcp-inspector-stdio-api-key-use-2.png)
   ![MCP Inspector Use](doc/mcp-inspector-stdio-api-key-use-3.png)

### 2๏ธโƒฃ MCP Server with Stdio and API Key (`mcp-server-with-stdio-jwt-key-auth.py`)

#### โ–ถ๏ธ **Run the MCP Server**:

โš ๏ธ *You do not need to manually run the MCP server for stdio transport. MCP Inspector will launch the server automatically.*

#### โ–ถ๏ธ **Run the MCP Inspector**:

The `stdio` server is typically launched by the MCP Inspector, not manually. Run the Inspector with the following command, adjusting the `--directory` path to your `src/` directory:

```bash
npx @modelcontextprotocol/inspector uv --directory '<your-src-directory>\src' run mcp-server-with-stdio-jwt-key-auth.py --debug
```

![MCP Inspector Run](doc/mcp-inspector-stdio-jwt-key-run-1.png)


#### ๐ŸŒ **Open the MCP Inspector**:

Open the link http://localhost:6274/?MCP_PROXY_AUTH_TOKEN=XXXXXXXXXXXXXXXXXX with its token in your browser:

![MCP Inspector Use](doc/mcp-inspector-stdio-jwt-key-open-1.png)

#### ๐Ÿงช **Using the MCP Inspector**

1. After running the above command, the Inspector will start and automatically connect to the `stdio`-based server.

2. **Usage Flow**:
   - **Step 1: Login to Get JWT Token**:
     ```json
     {
       "method": "call_tool",
       "params": {
         "name": "login",
         "arguments": {
           "username": "user1",
           "password": "password123"
         }
       }
     }
     ```
     **Response**:
     ```json
     {
       "result": [
         {
           "type": "text",
           "text": "Login successful! JWT Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
         }
       ]
     }
     ```

   - **Step 2: Use JWT Token for Authenticated Requests**:
     ```json
     {
       "method": "call_tool",
       "params": {
         "name": "echo",
         "arguments": {
           "message": "test",
           "_jwt_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
         }
       }
     }
     ```
     **Response**:
     ```json
     {
       "result": [
         {
           "type": "text",
           "text": "Echo (authenticated as user1): test"
         }
       ]
     }
     ```
   ![MCP Inspector Use](doc/mcp-inspector-stdio-jwt-key-use-1.png)
   ![MCP Inspector Use](doc/mcp-inspector-stdio-jwt-key-use-2.png)
   ![MCP Inspector Use](doc/mcp-inspector-stdio-jwt-key-use-3.png)
   ![MCP Inspector Use](doc/mcp-inspector-stdio-jwt-key-use-4.png)

### 3๏ธโƒฃ MCP Server with Stdio and Auth2 (`mcp-server-with-stdio-auth2-auth.py`)

๐Ÿšง **To Do**

---

## ๐Ÿ”„ Workflow

1. ๐Ÿ”‘ **API Key Authentication**:
   - The server checks for a valid API key in the request arguments, metadata, or environment variables.
   - If valid, the request is processed; otherwise, an error is returned.
   - The `echo` tool demonstrates basic functionality.

2. ๐Ÿ›ก๏ธ **JWT Authentication**:
   - Users first call the `login` tool with valid credentials to obtain a JWT token.
   - The token is used in subsequent requests for tools like `echo`, `secure_action`, or `admin_action`.
   - Permissions (`read`, `write`, `admin`) are checked for each tool.
   - Tokens expire after 24 hours (configurable).

3. ๐Ÿ“ **Logging**:
   - Logs are written to both the console and a rotating log file in the `logs` directory.
   - Old log files are cleaned up based on a specified retention period.

4. ๐Ÿ” **Testing with MCP Inspector**:
   - Use MCP Inspector to interact with the server via a web interface.
   - Debug mode (`--debug`) provides detailed output for troubleshooting.

## ๐Ÿฉต Troubleshooting

- ๐Ÿšซ **Invalid API Key**:
  - Ensure the API key is one of: `sk-1234567890abcdef`, `sk-abcdef1234567890`, `sk-test123456789`.
  - Check environment variable `MCP_API_KEY` or request arguments.

- โš ๏ธ **Invalid JWT Token**:
  - Verify the token is not expired (valid for 24 hours).
  - Ensure the correct `JWT_SECRET` is set.
  - Check username/password for `login` tool.

- ๐Ÿ”’ **Permission Errors**:
  - Ensure the user has the required permissions (`read`, `write`, or `admin`) for the requested tool.

- ๐Ÿ“ **Log Files**:
  - Check the `logs` directory for detailed error messages.
  - Logs are named in the format `YYYYMM.log`.

TDQS

C2.9/5.0

Scored across 1 tool

Disambiguation5/5

Only one tool exists, so there is no risk of confusion between tools.

Naming Consistency5/5

With a single tool named 'echo', naming consistency is trivially maintained.

Tool Count1/5

A server named 'MCP Server with Authentication' should have multiple tools related to authentication, but instead it has only one trivial echo tool.

Completeness1/5

The server's name suggests a focus on authentication, yet the tool surface is limited to echoing messages, leaving the entire authentication domain uncovered.

Maintenance

ActivityInactive
ResponsivenessNo issues