Skip to main content
Glama
Reality-Defender

Reality Defender MCP Server

Official
README.md
# Reality Defender MCP Server

A Model Context Protocol (MCP) server that provides AI-generated media detection capabilities using the Reality Defender API. This server enables LLMs to analyze images, videos, audio, and text files to determine if they were generated by AI.

## Features

- **AI Media Detection**: Analyze files for AI generation using Reality Defender's advanced detection models
- **Multiple Input Methods**: Support for both direct URL downloads and user file uploads
- **Comprehensive File Support**: Images, videos, audio, and text files
- **Web Upload Interface**: Built-in FastAPI web server for secure file uploads
- **Error Handling**: Robust error handling with user-friendly messages
- **Async Operations**: Modern async/await patterns for optimal performance

## Getting Started

### Prerequisites

- Python 3.12
- UV package and project manager
- Reality Defender API Key

### Installation

1. Clone the repository:
```bash
git clone https://github.com/Reality-Defender/eng-mcp-server.git
```

2. Install dependencies:
```bash
uv sync
```

3. Set up environment variables:
```bash
export REALITY_DEFENDER_API_KEY="your-api-key-here"
```

### Running the Server

#### MCP Server Mode

To run the MCP server:

```bash
uv run ./src/reality_defender_mcp_server/mcp_server.py
```

By default, the server also starts a small web server for file uploads. You can disable uploads entirely by setting `UPLOADS=false`.

To run MCP over Streamable HTTP (cloud-friendly):

```bash
FASTMCP_HOST=0.0.0.0 FASTMCP_PORT=8000 uv run ./src/reality_defender_mcp_server/mcp_server.py --transport streamable-http
```

By default, the Streamable HTTP MCP endpoint is served at `/mcp`.

#### Standalone Web Server

To run just the web server component:

```bash
uv run ./src/reality_defender_mcp_server/web_server.py [options]
```

Web server options:
- `--debug`: Enable debug logging
- `--host`: Server host (default: 127.0.0.1)
- `--port`: Server port (default: 8080)
- `--upload-dir`: Upload directory (default: ./uploads)

### MCP Client Configuration

Configure the server in your MCP client, e.g. for Claude Desktop:

```json
{
  "mcpServers": {
    "realitydefender": {
      "command": "uv",
      "args": [
        "--directory",
        "/path/to/eng-reality-defender-mcp-server",
        "run",
        "python",
        "mcp_server.py"
      ],
      "env": {
        "REALITY_DEFENDER_API_KEY": "your-api-key-here"
      }
    }
  }
}
```


## Configuration

The application uses environment variables for configuration:

| Variable | Description | Required | Default |
|----------|-------------|----------|---------|
| `REALITY_DEFENDER_API_KEY` | API key for Reality Defender service | Yes | - |
| `DEBUG` | Enable debug mode | No | false |
| `WEB_SERVER_HOST` | Host for the web server | No | 127.0.0.1 |
| `WEB_SERVER_PORT` | Port for the web server | No | 8080 |
| `WEB_SERVER_UPLOADS_DIR` | Directory for file uploads | No | ./uploads |
| `UPLOADS` | Enable local file upload workflow; set to `false` to disable uploads and only allow remote URLs | No | true |

### API Key Authentication

- By default, the server uses `REALITY_DEFENDER_API_KEY` from environment variables.
- For cloud deployments, clients can pass a request-scoped Reality Defender key using the `X-Api-Key` HTTP header.
- If `X-Api-Key` is present, it is used for that request and takes precedence over `REALITY_DEFENDER_API_KEY`.
- For security, prefer headers over URL query parameters for API keys.

## MCP Tools

The server provides the following MCP tools:

### `reality_defender_generate_upload_url`

Generates a unique upload URL for user file uploads.

**Returns:** `GenerateUploadUrlOutput | Error`

### `reality_defender_get_file_info`

Retrieves metadata about an uploaded or downloaded file.

**Parameters:**
- `file_id` (string): The file ID to retrieve metadata for

**Returns:** `GetFileInfoOutput | Error`

### `reality_defender_request_file_analysis`

Analyzes a file for AI generation using Reality Defender API.

**Parameters:**
- `request` (RealityDefenderAnalysisRequest): Analysis request with file path/URL and expected file type

**Returns:** `RealityDefenderAnalysisResponse | Error`

## Streamable HTTP Deployment

- Use `--transport streamable-http` to expose MCP over HTTP for cloud deployments.
- Configure bind host/port with `FASTMCP_HOST` and `FASTMCP_PORT`.
- Default MCP path is `/mcp` (configurable via FastMCP settings environment variables).
- Continue using `X-Api-Key` to pass request-scoped Reality Defender credentials.

## Container Publishing

- On pushes to `main`, GitHub Actions builds the Docker image from `Dockerfile`.
- The image is published to GitHub Container Registry as `ghcr.io/<owner>/eng-mcp-server`.
- Published tags include `latest`, `main`, and `sha-<commit>`.

## Usage Workflows

### User Upload Workflow (Recommended)

1. Generate upload URL using `reality_defender_generate_upload_url`
2. Direct user to upload file at the provided URL
3. Get file info using `reality_defender_get_file_info` with the UUID
4. Analyze file using `reality_defender_request_file_analysis`
5. Present results to user

### Direct URL Workflow

1. Analyze file directly using `reality_defender_request_file_analysis` with URL
2. Get additional file info using `reality_defender_get_file_info` if needed
3. Present results to user

## File Structure

Uploaded and downloaded files are organized as:

```
uploads/
└── {uuid}/
    ├── blob.{ext}     # Raw file data with proper extension
    └── metadata.json  # File metadata (filename, size, timestamp, MIME type, source)
```

## Development

### Code Standards

- **Type Hints**: Always use type hints for all functions and parameters
- **Modern Python**: Use Python 3.12 features and syntax (`str | None` instead of `Optional[str]`)
- **Async First**: Prefer async/await patterns where possible
- **Error Handling**: Return union types (`SuccessType | Error`) instead of raising exceptions
- **Pydantic Models**: Use Pydantic for all structured data validation

### Linting and Type Checking

```bash
# Type checking
basedpyright

# Linting and formatting
ruff check .
ruff format .
```

### Running Tests

```bash
pytest
```

## API Reference

### Web Server Endpoints

- `GET /` - Service information
- `GET /health` - Health check
- `GET /upload/{uuid}` - Upload form for specified UUID
- `POST /upload/{uuid}` - File upload endpoint
- `GET /docs` - OpenAPI documentation

Note: If `UPLOADS=false`, the upload web server is not started and only direct URL analysis is supported. The tools and responses will not suggest uploading files when uploads are disabled.

### Response Types

#### RealityDefenderAnalysisResponse

```python
{
    "status": "ARTIFICIAL" | "AUTHENTIC" | "ANALYZING",
    "score": float,  # Confidence score (0-100)
    "models": [      # Individual model results
        {
            "name": str,
            "status": str,
            "score": float | None
        }
    ],
    "file_id": str | None  # For downloaded files
}
```

## Troubleshooting

- **API Key Errors**: Verify your `REALITY_DEFENDER_API_KEY` is valid
- **File Upload Issues**: Check upload directory permissions and disk space
- **Network Errors**: Verify internet connectivity for URL downloads
- **Port Conflicts**: Use `--port` option to specify different port
- **Large Files**: Files are limited to 1MB via web interface